{"file_path":"src/StablecoinV1.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.34;\n\nimport {IERC20Metadata} from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {Ownable2StepUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport {Pausable} from \"./Pausable.sol\";\nimport {Blacklistable} from \"./Blacklistable.sol\";\nimport {Whitelistable} from \"./Whitelistable.sol\";\nimport {Seizable} from \"./Seizable.sol\";\nimport {AssetRecovery} from \"./AssetRecovery.sol\";\nimport {EIP2612} from \"./EIP2612.sol\";\nimport {ERC3009Upgradeable} from \"./ERC3009.sol\";\n\n/**\n * @title StablecoinV1\n * @notice JPY-backed stablecoin implementing ERC-20 with pause, blacklist, per-minter destination\n *         whitelist, court-ordered seizure, EIP-2612 permit, ERC-3009 gasless transfers, and\n *         UUPS upgradeability. Designed for Type-3 trust-bank stablecoins with strict 1:1 fiat backing.\n * @dev Inherits Pausable, Blacklistable, Whitelistable, Seizable, AssetRecovery, EIP2612, ERC3009, and\n *      Ownable2StepUpgradeable. All state is stored in an ERC-7201 namespaced slot to prevent storage\n *      collisions across upgrades. Role assignments use a dual-access pattern — callable by the current\n *      role holder OR the Owner.\n */\ncontract StablecoinV1 is\n    Initializable,\n    IERC20Metadata,\n    Pausable,\n    Blacklistable,\n    Whitelistable,\n    Seizable,\n    AssetRecovery,\n    EIP2612,\n    ERC3009Upgradeable,\n    Ownable2StepUpgradeable,\n    UUPSUpgradeable\n{\n    // ============ Storage ============\n\n    /// @custom:storage-location erc7201:jpysc.storage.StablecoinV1\n    struct StablecoinV1Storage {\n        string _name;\n        string _symbol;\n        string _currency;\n        uint8 _decimals;\n        uint256 _totalSupply;\n        mapping(address => uint256) _balances;\n        mapping(address => mapping(address => uint256)) _allowances;\n        address _minterAdmin;\n        mapping(address => bool) _minters;\n        mapping(address => uint256) _minterAllowances;\n        address _upgradeAuthority;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"jpysc.storage.StablecoinV1\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant STABLECOIN_V1_STORAGE_LOCATION =\n        0x6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf900;\n\n    function _getStablecoinV1Storage() private pure returns (StablecoinV1Storage storage $) {\n        assembly {\n            $.slot := STABLECOIN_V1_STORAGE_LOCATION\n        }\n    }\n\n    /// @notice Contract version. Included in the EIP-712 domain separator used by EIP-2612 and ERC-3009.\n    string public constant VERSION = \"1\";\n\n    // ============ Events ============\n\n    event Mint(address indexed minter, address indexed to, uint256 amount);\n    event Burn(address indexed burner, uint256 amount);\n    event MinterConfigured(address indexed minter, uint256 minterAllowedAmount);\n    event MinterRemoved(address indexed minter);\n    event MinterAdminChanged(address indexed previousMinterAdmin, address indexed newMinterAdmin);\n    event UpgradeAuthorityChanged(address indexed previousUpgradeAuthority, address indexed newUpgradeAuthority);\n\n    // ============ Errors ============\n\n    error NotMinter(address account);\n    error NotMinterAdmin(address account);\n    error InvalidMinterAdmin(address minterAdmin);\n    error MintExceedsAllowance(uint256 amount, uint256 allowance);\n    error BurnExceedsBalance(uint256 amount, uint256 balance);\n    error InsufficientBalance(address account, uint256 amount, uint256 balance);\n    error InsufficientAllowance(address spender, uint256 amount, uint256 allowance);\n    error InvalidReceiver(address receiver);\n    error InvalidSender(address sender);\n    error InvalidSpender(address spender);\n    error MinterWhitelistManagerSeparationViolation(address account);\n    error BlacklisterSeizerSeparationViolation(address account);\n    error MinterAllowanceNotZero(address minter);\n    /// @dev Thrown by configureMinter when allowance_ == 0 and the address is already a registered\n    ///      minter. Re-configuring an active minter to zero allowance without going through\n    ///      removeMinter first would be a silent no-op (state unchanged, spurious event emitted).\n    ///      To create a burn-only minter, pass allowance_ == 0 for an address that is NOT yet registered.\n    error InvalidMinterAllowance();\n    /// @dev Thrown by mint() when amount is zero. A zero-amount mint changes no state but\n    ///      would emit spurious Mint and Transfer events, so it is rejected unconditionally.\n    error InvalidMintAmount();\n    error NotUpgradeAuthority(address account);\n    error InvalidUpgradeAuthority(address account);\n    error UpgradeAuthorityOwnerSeparationViolation(address account);\n\n    // ============ Modifiers ============\n\n    /// @dev Reverts with `NotMinter` if the caller is not a configured minter.\n    modifier onlyMinter() {\n        if (!_getStablecoinV1Storage()._minters[msg.sender]) {\n            revert NotMinter(msg.sender);\n        }\n        _;\n    }\n\n    /// @dev Reverts with `NotMinterAdmin` if the caller is not the minter admin.\n    modifier onlyMinterAdmin() {\n        if (msg.sender != _getStablecoinV1Storage()._minterAdmin) {\n            revert NotMinterAdmin(msg.sender);\n        }\n        _;\n    }\n\n    /// @dev Reverts with `NotUpgradeAuthority` if the caller is not the designated upgrade authority.\n    modifier onlyUpgradeAuthority() {\n        if (msg.sender != _getStablecoinV1Storage()._upgradeAuthority) {\n            revert NotUpgradeAuthority(msg.sender);\n        }\n        _;\n    }\n\n    // ============ Constructor ============\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    /// @dev Calls `_disableInitializers` so the implementation contract can never be initialized directly,\n    ///      preventing an attacker from taking ownership of the bare implementation.\n    constructor() {\n        _disableInitializers();\n    }\n\n    // ============ Initialization ============\n\n    /**\n     * @notice Initializes the token contract. Can only be called once via the proxy (V1 fresh deployment).\n     * @dev Sets token metadata, wires up all module initializers, and assigns each operational role.\n     *      Reverts if `initialMinterAdmin == initialWhitelistManager` to enforce key separation.\n     *      All role addresses must be non-zero; each `_initializeXxx` call enforces this.\n     * @param tokenName       ERC-20 name (e.g. \"JPY Stablecoin\").\n     * @param tokenSymbol     ERC-20 ticker symbol (e.g. \"JPYSC\").\n     * @param tokenCurrency   ISO 4217 currency code (e.g. \"JPY\").\n     * @param tokenDecimals   Number of decimals (typically 18).\n     * @param initialOwner    Address to receive contract ownership (two-step Ownable2Step).\n     * @param initialPauser   Address that can pause / unpause the contract.\n     * @param initialBlacklister    Address that can blacklist / unblacklist accounts.\n     * @param initialAssetRecoverer Address that can recover mistakenly sent ERC-20 tokens.\n     * @param initialSeizer         Address that can execute court-ordered forced transfers.\n     * @param initialMinterAdmin    Address that can configure and remove minters. Must differ from\n     *                              `initialWhitelistManager`.\n     * @param initialWhitelistManager Address that manages per-minter mint destination whitelists. Must\n     *                                differ from `initialMinterAdmin`.\n     * @param initialUpgradeAuthority Address that may call `upgradeToAndCall`. Must differ from\n     *                                `initialOwner` to enforce separation of upgrade authority from\n     *                                operational ownership. In production this should be set to a\n     *                                TimelockController address (see Operation_Procedure.md §10).\n     */\n    function initialize(\n        string memory tokenName,\n        string memory tokenSymbol,\n        string memory tokenCurrency,\n        uint8 tokenDecimals,\n        address initialOwner,\n        address initialPauser,\n        address initialBlacklister,\n        address initialAssetRecoverer,\n        address initialSeizer,\n        address initialMinterAdmin,\n        address initialWhitelistManager,\n        address initialUpgradeAuthority\n    ) external initializer {\n        __Ownable_init(initialOwner);\n        __JPYSCPausable_init();\n        __Blacklistable_init();\n        __Whitelistable_init();\n        __Seizable_init();\n        __AssetRecovery_init();\n        __EIP2612_init(tokenName, VERSION);\n        __EIP3009_init();\n\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        $._name = tokenName;\n        $._symbol = tokenSymbol;\n        $._currency = tokenCurrency;\n        $._decimals = tokenDecimals;\n\n        if (initialMinterAdmin == initialWhitelistManager) {\n            revert MinterWhitelistManagerSeparationViolation(initialMinterAdmin);\n        }\n        // Enforce blacklister ≠ seizer: a single address holding both roles would allow\n        // one compromised key to blacklist and seize without a second authorization.\n        if (initialBlacklister == initialSeizer) {\n            revert BlacklisterSeizerSeparationViolation(initialBlacklister);\n        }\n\n        _initializePauser(initialPauser);\n        _initializeBlacklister(initialBlacklister);\n        _initializeAssetRecoverer(initialAssetRecoverer);\n        _initializeSeizer(initialSeizer);\n        _initializeMinterAdmin(initialMinterAdmin);\n        _initializeWhitelistManager(initialWhitelistManager);\n\n        if (initialUpgradeAuthority == address(0)) revert InvalidUpgradeAuthority(address(0));\n        if (initialUpgradeAuthority == initialOwner) {\n            revert UpgradeAuthorityOwnerSeparationViolation(initialUpgradeAuthority);\n        }\n        $._upgradeAuthority = initialUpgradeAuthority;\n        emit UpgradeAuthorityChanged(address(0), initialUpgradeAuthority);\n    }\n\n    // ============ UUPS Upgrade Authorization ============\n\n    /// @notice Returns the address currently authorized to perform implementation upgrades.\n    /// @dev In production this should be a TimelockController. See Operation_Procedure.md §10.\n    function upgradeAuthority() external view returns (address) {\n        return _getStablecoinV1Storage()._upgradeAuthority;\n    }\n\n    /// @notice Transfers upgrade authority to `newUpgradeAuthority`.\n    /// @dev Only the current upgrade authority can call this — the Owner cannot. This ensures\n    ///      that any change to upgrade authority also goes through the TimelockController delay.\n    ///      Pass the new TimelockController address when migrating governance.\n    /// @param newUpgradeAuthority New address to hold upgrade rights. Must be non-zero.\n    function updateUpgradeAuthority(address newUpgradeAuthority) external onlyUpgradeAuthority {\n        if (newUpgradeAuthority == address(0)) revert InvalidUpgradeAuthority(address(0));\n        if (newUpgradeAuthority == owner()) revert UpgradeAuthorityOwnerSeparationViolation(newUpgradeAuthority);\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        address old = $._upgradeAuthority;\n        $._upgradeAuthority = newUpgradeAuthority;\n        emit UpgradeAuthorityChanged(old, newUpgradeAuthority);\n    }\n\n    /// @dev Called by the UUPS proxy before executing an upgrade. Restricted to the upgrade authority\n    ///      (not the Owner). In production the upgrade authority is a TimelockController, ensuring\n    ///      a mandatory delay (≥ 48 h) and multi-sig approval before any implementation change.\n    ///      OpenZeppelin's proxy validates `proxiableUUID()` on the new implementation before\n    ///      writing the new address, protecting against accidentally bricking the proxy.\n    /// @param newImplementation Address of the new implementation contract.\n    function _authorizeUpgrade(address newImplementation) internal virtual override onlyUpgradeAuthority {}\n\n    // ============ Ownership — Force 2-Step Only ============\n\n    /**\n     * @notice Permanently disabled. Ownership of the stablecoin proxy must always be held by a\n     *         known account; losing it irrecoverably would brick upgrades and all owner-gated functions.\n     * @dev Always reverts. Use the two-step path instead:\n     *        1. `transferOwnership(newOwner)` — nominates the new owner\n     *        2. `acceptOwnership()`           — new owner confirms and takes effect\n     */\n    function renounceOwnership() public virtual override onlyOwner {\n        revert(\"renounceOwnership disabled\");\n    }\n\n    /**\n     * @notice Nominates `newOwner` as the pending owner (two-step transfer).\n     * @dev Reverts if `newOwner` equals the current upgradeAuthority — the separation\n     *      between owner and upgrade authority must be maintained at all times.\n     */\n    function transferOwnership(address newOwner) public virtual override {\n        if (newOwner == _getStablecoinV1Storage()._upgradeAuthority) {\n            revert UpgradeAuthorityOwnerSeparationViolation(newOwner);\n        }\n        super.transferOwnership(newOwner);\n    }\n\n    // ============ ERC20 Metadata ============\n\n    /// @notice Returns the name of the token (e.g. \"JPY Stablecoin\").\n    /// @return Token name set at initialization.\n    function name() external view override returns (string memory) {\n        return _getStablecoinV1Storage()._name;\n    }\n\n    /// @notice Returns the ticker symbol of the token (e.g. \"JPYSC\").\n    /// @return Token symbol set at initialization.\n    function symbol() external view override returns (string memory) {\n        return _getStablecoinV1Storage()._symbol;\n    }\n\n    /// @notice Returns the ISO 4217 fiat currency this token is backed by (e.g. \"JPY\").\n    /// @return Currency code set at initialization.\n    function currency() external view returns (string memory) {\n        return _getStablecoinV1Storage()._currency;\n    }\n\n    /// @notice Returns the number of decimal places used by the token (typically 18).\n    /// @return Decimal count set at initialization.\n    function decimals() external view override returns (uint8) {\n        return _getStablecoinV1Storage()._decimals;\n    }\n\n    // ============ ERC20 Core ============\n\n    /// @notice Returns the total number of tokens in existence.\n    /// @return Current total supply.\n    function totalSupply() external view override returns (uint256) {\n        return _getStablecoinV1Storage()._totalSupply;\n    }\n\n    /// @notice Returns the token balance of `account`.\n    /// @param account Address to query.\n    /// @return Balance of `account`.\n    function balanceOf(address account) external view override returns (uint256) {\n        return _getStablecoinV1Storage()._balances[account];\n    }\n\n    /// @notice Transfers `amount` tokens from the caller to `to`.\n    /// @dev Reverts if the contract is paused or if either `msg.sender` or `to` is blacklisted.\n    /// @param to     Recipient address.\n    /// @param amount Number of tokens to transfer.\n    /// @return True on success.\n    function transfer(address to, uint256 amount)\n        external\n        virtual\n        override\n        whenNotPaused\n        notBlacklisted(msg.sender)\n        notBlacklisted(to)\n        returns (bool)\n    {\n        _transfer(msg.sender, to, amount);\n        return true;\n    }\n\n    /// @notice Returns the number of tokens that `spender` is allowed to spend on behalf of `owner_`.\n    /// @param owner_   Token owner address.\n    /// @param spender  Spender address.\n    /// @return Remaining allowance.\n    function allowance(address owner_, address spender) external view override returns (uint256) {\n        return _getStablecoinV1Storage()._allowances[owner_][spender];\n    }\n\n    /// @notice Approves `spender` to spend `amount` tokens on behalf of the caller.\n    /// @dev Reverts if the contract is paused or if either `msg.sender` or `spender` is blacklisted.\n    ///      Setting a non-zero allowance on top of an existing non-zero allowance is permitted;\n    ///      callers should use `increaseAllowance` / `decreaseAllowance` to avoid the classic\n    ///      double-spend race condition.\n    /// @param spender Address authorized to spend tokens.\n    /// @param amount  Allowance amount.\n    /// @return True on success.\n    function approve(address spender, uint256 amount)\n        external\n        virtual\n        override\n        whenNotPaused\n        notBlacklisted(msg.sender)\n        notBlacklisted(spender)\n        returns (bool)\n    {\n        _approve(msg.sender, spender, amount);\n        return true;\n    }\n\n    /// @notice Transfers `amount` tokens from `from` to `to` using the caller's allowance.\n    /// @dev Reverts if the contract is paused or if any of `msg.sender`, `from`, or `to` is\n    ///      blacklisted. Decrements the caller's allowance unless it is `type(uint256).max`.\n    /// @param from   Source address.\n    /// @param to     Destination address.\n    /// @param amount Number of tokens to transfer.\n    /// @return True on success.\n    function transferFrom(address from, address to, uint256 amount)\n        external\n        virtual\n        override\n        whenNotPaused\n        notBlacklisted(msg.sender)\n        notBlacklisted(from)\n        notBlacklisted(to)\n        returns (bool)\n    {\n        _spendAllowance(from, msg.sender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    // ============ ERC20 Extensions ============\n\n    /// @notice Increases the allowance granted to `spender` by `addedValue`.\n    /// @dev Reverts if the contract is paused or if either `msg.sender` or `spender` is blacklisted.\n    ///      Preferred over `approve` when adding to an existing allowance to avoid the double-spend\n    ///      race condition.\n    /// @param spender    Address whose allowance is increased.\n    /// @param addedValue Amount to add to the current allowance.\n    /// @return True on success.\n    function increaseAllowance(address spender, uint256 addedValue)\n        external\n        whenNotPaused\n        notBlacklisted(msg.sender)\n        notBlacklisted(spender)\n        returns (bool)\n    {\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        _approve(msg.sender, spender, $._allowances[msg.sender][spender] + addedValue);\n        return true;\n    }\n\n    /// @notice Decreases the allowance granted to `spender` by `subtractedValue`.\n    /// @dev Reverts if the contract is paused, if either `msg.sender` or `spender` is blacklisted,\n    ///      or if `subtractedValue` exceeds the current allowance.\n    /// @param spender         Address whose allowance is decreased.\n    /// @param subtractedValue Amount to subtract from the current allowance.\n    /// @return True on success.\n    function decreaseAllowance(address spender, uint256 subtractedValue)\n        external\n        whenNotPaused\n        notBlacklisted(msg.sender)\n        notBlacklisted(spender)\n        returns (bool)\n    {\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        uint256 currentAllowance = $._allowances[msg.sender][spender];\n        if (subtractedValue > currentAllowance) {\n            revert InsufficientAllowance(spender, subtractedValue, currentAllowance);\n        }\n        unchecked {\n            _approve(msg.sender, spender, currentAllowance - subtractedValue);\n        }\n        return true;\n    }\n\n    // ============ EIP-2612 Permit ============\n\n    /// @notice Sets an allowance via an off-chain EIP-712 signature, enabling gasless approvals.\n    /// @dev Reverts if the contract is paused, if `owner_`, `spender`, or `msg.sender` is blacklisted,\n    ///      if the deadline has passed, or if the recovered signer does not match `owner_`.\n    ///      `msg.sender` (the relayer) is checked for consistency with other gasless entry points —\n    ///      a blacklisted relayer must not be able to submit permits on behalf of others, even though\n    ///      the relayer gains no token capability from doing so.\n    /// @param owner_   Token owner who signed the permit.\n    /// @param spender  Address being approved to spend tokens.\n    /// @param value    Allowance amount.\n    /// @param deadline Unix timestamp after which the signature is invalid.\n    /// @param v        Signature component.\n    /// @param r        Signature component.\n    /// @param s        Signature component.\n    function permit(address owner_, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)\n        external\n        virtual\n        whenNotPaused\n        notBlacklisted(msg.sender)\n        notBlacklisted(owner_)\n        notBlacklisted(spender)\n    {\n        _permit(owner_, spender, value, deadline, v, r, s);\n        _approve(owner_, spender, value);\n    }\n\n    // ============ ERC-3009 Transfer With Authorization ============\n\n    /// @notice Executes a token transfer on behalf of `from` using an ERC-3009 off-chain authorization.\n    /// @dev Reverts if the contract is paused, if `from`, `to`, or `msg.sender` is blacklisted, if the\n    ///      authorization signature is invalid, if the nonce has already been used, or if the timestamp\n    ///      is outside the open interval `(validAfter, validBefore)` — both bounds are exclusive.\n    ///      `msg.sender` (the relayer) is checked for consistency with other gasless entry points —\n    ///      a blacklisted relayer must not be able to submit transfer authorizations on behalf of others,\n    ///      even though the relayer gains no token capability from doing so.\n    /// @param from        Token sender who signed the authorization.\n    /// @param to          Recipient address.\n    /// @param value       Amount of tokens to transfer.\n    /// @param validAfter  Unix timestamp; authorization is invalid at or before this time.\n    /// @param validBefore Unix timestamp; authorization is invalid at or after this time.\n    /// @param nonce       Unique nonce chosen by `from` to prevent replay.\n    /// @param v           Signature component.\n    /// @param r           Signature component.\n    /// @param s           Signature component.\n    function transferWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external virtual whenNotPaused notBlacklisted(msg.sender) notBlacklisted(from) notBlacklisted(to) {\n        _transferWithAuthorization(from, to, value, validAfter, validBefore, nonce, v, r, s);\n        _transfer(from, to, value);\n    }\n\n    /// @notice Like `transferWithAuthorization` but requires `msg.sender == to`, preventing\n    ///         front-running by ensuring only the intended recipient can submit the authorization.\n    /// @dev Reverts if `msg.sender != to` in addition to all checks in `transferWithAuthorization`.\n    ///      The valid time window is the open interval `(validAfter, validBefore)` — both exclusive.\n    /// @param from        Token sender who signed the authorization.\n    /// @param to          Recipient address (must equal `msg.sender`).\n    /// @param value       Amount of tokens to transfer.\n    /// @param validAfter  Unix timestamp; authorization is invalid at or before this time.\n    /// @param validBefore Unix timestamp; authorization is invalid at or after this time.\n    /// @param nonce       Unique nonce chosen by `from` to prevent replay.\n    /// @param v           Signature component.\n    /// @param r           Signature component.\n    /// @param s           Signature component.\n    function receiveWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external virtual whenNotPaused notBlacklisted(from) notBlacklisted(to) {\n        _receiveWithAuthorization(from, to, value, validAfter, validBefore, nonce, v, r, s);\n        _transfer(from, to, value);\n    }\n\n    /// @notice Cancels an unused ERC-3009 authorization, preventing it from ever being submitted.\n    /// @dev Intentionally not gated by `whenNotPaused` — the authorizer must always be able to\n    ///      invalidate a signature even during a pause. Reverts if the signature does not match\n    ///      `authorizer` or if `nonce` is already cancelled or used.\n    ///      `msg.sender` blacklist check is intentionally omitted: a blacklisted authorizer must\n    ///      still be able to cancel their own pending signatures (cancellation reduces risk), and a\n    ///      blacklisted third-party relayer gains no token capability from submitting a cancellation.\n    /// @param authorizer Address that originally signed the authorization.\n    /// @param nonce      Nonce of the authorization to cancel.\n    /// @param v          Signature component.\n    /// @param r          Signature component.\n    /// @param s          Signature component.\n    function cancelAuthorization(address authorizer, bytes32 nonce, uint8 v, bytes32 r, bytes32 s) external virtual {\n        _cancelAuthorization(authorizer, nonce, v, r, s);\n    }\n\n    // ============ Minting ============\n\n    /// @notice Returns the address of the minter admin, who manages minter configuration.\n    /// @return Current minter admin address.\n    function minterAdmin() external view returns (address) {\n        return _getStablecoinV1Storage()._minterAdmin;\n    }\n\n    /// @notice Returns whether `account` is a configured minter.\n    /// @param account Address to check.\n    /// @return True if `account` is a minter.\n    function isMinter(address account) external view returns (bool) {\n        return _getStablecoinV1Storage()._minters[account];\n    }\n\n    /// @notice Returns the remaining mint allowance for `minter`.\n    /// @dev Allowance is decremented on each successful `mint` call and reset by `configureMinter`.\n    /// @param minter Minter address to query.\n    /// @return Remaining mint allowance in token units.\n    function minterAllowance(address minter) external view returns (uint256) {\n        return _getStablecoinV1Storage()._minterAllowances[minter];\n    }\n\n    /// @notice Grants or renews a minter allowance, or creates a burn-only minter.\n    /// @dev Only callable by the minter admin. Reverts if:\n    ///      - `minter` is the current whitelist manager (key separation)\n    ///      - `minter` is currently blacklisted (prevents loading a dormant allowance that would\n    ///        activate silently if the address is later unblacklisted; if a minter is blacklisted\n    ///        as a compliance action, call `removeMinter` first — see Operation_Procedure.md §7)\n    ///      - the minter's current allowance is non-zero (`MinterAllowanceNotZero`)\n    ///      - `allowance_` is zero AND `minter` is already a registered minter\n    ///        (`InvalidMinterAllowance` — re-configuring an active minter to zero without going\n    ///        through `removeMinter` is a no-op and would only emit a spurious event)\n    ///\n    ///      The non-zero allowance guard prevents the ERC-20 approve double-spend: a minter\n    ///      observing a pending `configureMinter` reduction in the mempool could front-run it by\n    ///      minting their full remainder first. By requiring the current allowance to be zero before\n    ///      any reconfiguration, there is no remainder to race against.\n    ///\n    ///      To change the allowance of a minter whose current allowance is non-zero, use the\n    ///      safe two-step process:\n    ///        1. Call `removeMinter(minter)` — atomically zeros the allowance on-chain.\n    ///        2. Wait for confirmation, then call `configureMinter(minter, newAllowance)`.\n    ///\n    ///      If a minter has naturally exhausted their allowance (minted up to the limit so the\n    ///      stored value is 0), `configureMinter` can be called directly without `removeMinter`.\n    ///\n    ///      Burn-only minters: passing `allowance_ == 0` for an address that is NOT yet registered\n    ///      creates a burn-only minter (_minters[minter] = true, _minterAllowances[minter] = 0).\n    ///      Such a minter can call burn() — which only checks onlyMinter and never reads allowance —\n    ///      but any mint() call will revert: InvalidMintAmount if amount == 0, or\n    ///      MintExceedsAllowance if amount > 0 (since 0 allowance is always exceeded).\n    ///      A burn-only minter can be promoted to a full minter by calling\n    ///      configureMinter(minter, nonZeroAllowance) directly, without removeMinter. This is safe\n    ///      because a zero-allowance minter has nothing to front-run.\n    ///      See Operation_Procedure.md for the burn-only minter lifecycle.\n    /// @param minter     Address to grant minting rights to. Must not be blacklisted.\n    /// @param allowance_ New allowance. Pass 0 to create a burn-only minter (address must not yet\n    ///                   be registered); pass a positive value to grant full minting capability.\n    /// @return True on success.\n    function configureMinter(address minter, uint256 allowance_)\n        external\n        onlyMinterAdmin\n        notBlacklisted(minter)\n        returns (bool)\n    {\n        if (minter == whitelistManager()) {\n            revert MinterWhitelistManagerSeparationViolation(minter);\n        }\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        if ($._minterAllowances[minter] != 0) revert MinterAllowanceNotZero(minter);\n        if ($._minters[minter] && allowance_ == 0) revert InvalidMinterAllowance();\n        $._minters[minter] = true;\n        $._minterAllowances[minter] = allowance_;\n        emit MinterConfigured(minter, allowance_);\n        return true;\n    }\n\n    /// @notice Removes `minter` from the minter set and clears their allowance to zero.\n    /// @dev Only callable by the minter admin. Does not revert if `minter` is not a minter\n    ///      (idempotent). Required first step when reducing or replacing a non-zero allowance —\n    ///      call this, wait for confirmation, then call `configureMinter` with the new value.\n    ///      See `configureMinter` for the full rationale.\n    ///      Per-minter whitelist entries are NOT cleared — the zeroed allowance is the effective\n    ///      security gate. If this address is later re-configured via `configureMinter`, all prior\n    ///      destinations become immediately active. The minter admin must coordinate with the\n    ///      whitelist manager to audit stale entries before re-activating a removed minter.\n    /// @param minter Address to remove.\n    /// @return True on success.\n    function removeMinter(address minter) external onlyMinterAdmin returns (bool) {\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        $._minters[minter] = false;\n        $._minterAllowances[minter] = 0;\n        emit MinterRemoved(minter);\n        return true;\n    }\n\n    // ============ Mint Destination Whitelist ============\n\n    /// @notice Whitelists `account` as a valid mint destination for `minter`.\n    /// @dev Only callable by the whitelist manager. Must be called before `minter` can mint to `account`.\n    ///      Whitelist entries are per-minter; whitelisting for one minter does not apply to others.\n    /// @param minter  Minter address for whom the destination is being whitelisted.\n    /// @param account Address to add to `minter`'s whitelist.\n    function whitelistMintDestination(address minter, address account) external onlyWhitelistManager {\n        _whitelistMintDestination(minter, account);\n    }\n\n    /// @notice Removes `account` from `minter`'s mint destination whitelist.\n    /// @dev Only callable by the whitelist manager. After removal, `minter` can no longer mint to\n    ///      `account` until re-whitelisted.\n    /// @param minter  Minter address for whom the destination is being removed.\n    /// @param account Address to remove from `minter`'s whitelist.\n    function unwhitelistMintDestination(address minter, address account) external onlyWhitelistManager {\n        _unwhitelistMintDestination(minter, account);\n    }\n\n    /// @notice Mints `amount` tokens to `to`, reducing the caller's mint allowance accordingly.\n    /// @dev Requires the contract to not be paused, the caller to be a configured minter, neither\n    ///      the caller nor `to` to be blacklisted, and `to` to be whitelisted for the calling minter.\n    ///      Reverts with `MintExceedsAllowance` if `amount` exceeds the caller's remaining allowance.\n    ///      Reverts with `InvalidMintAmount` if `amount` is zero (prevents spurious events and\n    ///      ensures burn-only minters — who have zero allowance — cannot call mint at all).\n    /// @param to     Recipient of the newly minted tokens. Must be whitelisted for the calling minter.\n    /// @param amount Number of tokens to mint. Must be greater than zero.\n    /// @return True on success.\n    function mint(address to, uint256 amount)\n        external\n        virtual\n        whenNotPaused\n        onlyMinter\n        notBlacklisted(msg.sender)\n        notBlacklisted(to)\n        onlyWhitelisted(to)\n        returns (bool)\n    {\n        if (amount == 0) revert InvalidMintAmount();\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        uint256 mintAllowance = $._minterAllowances[msg.sender];\n        if (amount > mintAllowance) {\n            revert MintExceedsAllowance(amount, mintAllowance);\n        }\n\n        unchecked {\n            $._minterAllowances[msg.sender] = mintAllowance - amount;\n        }\n\n        $._totalSupply += amount;\n        $._balances[to] += amount;\n\n        emit Mint(msg.sender, to, amount);\n        emit Transfer(address(0), to, amount);\n        return true;\n    }\n\n    // ============ Burning ============\n\n    /// @notice Burns `amount` tokens from the caller's balance, reducing the total supply.\n    /// @dev Only callable by a configured minter. Reverts if the contract is paused, if the caller\n    ///      is blacklisted, or if `amount` exceeds the caller's balance. Burning does not affect\n    ///      the caller's remaining mint allowance — it represents redemption of the underlying fiat.\n    /// @param amount Number of tokens to burn.\n    function burn(uint256 amount) external virtual whenNotPaused onlyMinter notBlacklisted(msg.sender) {\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        uint256 balance = $._balances[msg.sender];\n        if (amount > balance) {\n            revert BurnExceedsBalance(amount, balance);\n        }\n\n        unchecked {\n            $._balances[msg.sender] = balance - amount;\n        }\n        $._totalSupply -= amount;\n\n        emit Burn(msg.sender, amount);\n        emit Transfer(msg.sender, address(0), amount);\n    }\n\n    // ============ Seize (Court-Ordered Forced Transfer) ============\n\n    /// @notice Forcibly transfers `amount` tokens from `from` to `to` under a court order.\n    /// @dev Only callable by the seizer. `from` must already be blacklisted (enforced two-step:\n    ///      blacklister acts first, seizer second — a single compromised key cannot drain accounts).\n    ///      `to` must not be blacklisted. Works even when the contract is paused. Preserves total\n    ///      supply (no tokens are created or destroyed). The `trackId` is an indexed event field\n    ///      intended to reference the court order for auditability.\n    /// @param from    Source address. Must be non-zero and blacklisted.\n    /// @param to      Destination address. Must be non-zero and not blacklisted.\n    /// @param amount  Number of tokens to seize. Must not exceed `from`'s balance.\n    /// @param trackId Court order reference (e.g. `keccak256` of a document hash or case number).\n    function seize(address from, address to, uint256 amount, bytes32 trackId)\n        external\n        virtual\n        onlySeizer\n        notBlacklisted(to)\n    {\n        if (from == address(0)) {\n            revert SeizeFromZeroAddress();\n        }\n        if (to == address(0)) {\n            revert SeizeToZeroAddress();\n        }\n        if (!isBlacklisted(from)) {\n            revert SeizeFromNotBlacklisted(from);\n        }\n\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        uint256 fromBalance = $._balances[from];\n        if (amount > fromBalance) {\n            revert SeizeAmountExceedsBalance(from, amount, fromBalance);\n        }\n\n        unchecked {\n            $._balances[from] = fromBalance - amount;\n            $._balances[to] += amount;\n        }\n\n        emit Seized(from, to, amount, trackId);\n        emit Transfer(from, to, amount);\n    }\n\n    // ============ Role Updates ============\n\n    /// @notice Transfers the pauser role to `newPauser`.\n    /// @dev Dual-access: callable by the current pauser OR the Owner. Reverts if `newPauser` is\n    ///      `address(0)`. The Owner override allows recovery if the current key is lost or compromised.\n    /// @param newPauser Address to assign as the new pauser.\n    function updatePauser(address newPauser) external virtual {\n        if (msg.sender != pauser()) {\n            _checkOwner();\n        }\n        if (newPauser == address(0)) {\n            revert InvalidPauser(address(0));\n        }\n        _setPauser(newPauser);\n    }\n\n    /// @notice Transfers the blacklister role to `newBlacklister`.\n    /// @dev Dual-access: callable by the current blacklister OR the Owner. Reverts if\n    ///      `newBlacklister` is `address(0)` or equals the current seizer (role separation\n    ///      enforcement: a single key must not hold both roles simultaneously).\n    /// @param newBlacklister Address to assign as the new blacklister.\n    function updateBlacklister(address newBlacklister) external virtual {\n        if (msg.sender != blacklister()) {\n            _checkOwner();\n        }\n        if (newBlacklister == address(0)) {\n            revert InvalidBlacklister(address(0));\n        }\n        if (newBlacklister == seizer()) {\n            revert BlacklisterSeizerSeparationViolation(newBlacklister);\n        }\n        _setBlacklister(newBlacklister);\n    }\n\n    /// @notice Transfers the seizer role to `newSeizer`.\n    /// @dev Dual-access: callable by the current seizer OR the Owner. Reverts if `newSeizer` is\n    ///      `address(0)` or equals the current blacklister (role separation enforcement: a single\n    ///      key must not hold both roles simultaneously).\n    /// @param newSeizer Address to assign as the new seizer.\n    function updateSeizer(address newSeizer) external virtual {\n        if (msg.sender != seizer()) {\n            _checkOwner();\n        }\n        if (newSeizer == address(0)) {\n            revert InvalidSeizer(address(0));\n        }\n        if (newSeizer == blacklister()) {\n            revert BlacklisterSeizerSeparationViolation(newSeizer);\n        }\n        _setSeizer(newSeizer);\n    }\n\n    /// @notice Transfers the asset recoverer role to `newRecoverer`.\n    /// @dev Dual-access: callable by the current asset recoverer OR the Owner. Reverts if\n    ///      `newRecoverer` is `address(0)`.\n    /// @param newRecoverer Address to assign as the new asset recoverer.\n    function updateAssetRecoverer(address newRecoverer) external virtual {\n        if (msg.sender != assetRecoverer()) {\n            _checkOwner();\n        }\n        if (newRecoverer == address(0)) {\n            revert InvalidAssetRecoverer(address(0));\n        }\n        _setAssetRecoverer(newRecoverer);\n    }\n\n    /// @notice Transfers the whitelist manager role to `newWhitelistManager`.\n    /// @dev Dual-access: callable by the current whitelist manager OR the Owner. Reverts if\n    ///      `newWhitelistManager` is `address(0)`, is an existing minter, or is the minter admin\n    ///      (enforces minter / whitelist manager key separation).\n    /// @param newWhitelistManager Address to assign as the new whitelist manager.\n    function updateWhitelistManager(address newWhitelistManager) external virtual {\n        if (msg.sender != whitelistManager()) {\n            _checkOwner();\n        }\n        if (newWhitelistManager == address(0)) {\n            revert InvalidWhitelistManager(address(0));\n        }\n        if (_getStablecoinV1Storage()._minters[newWhitelistManager]) {\n            revert MinterWhitelistManagerSeparationViolation(newWhitelistManager);\n        }\n        if (newWhitelistManager == _getStablecoinV1Storage()._minterAdmin) {\n            revert MinterWhitelistManagerSeparationViolation(newWhitelistManager);\n        }\n        _setWhitelistManager(newWhitelistManager);\n    }\n\n    /// @notice Transfers the minter admin role to `newMinterAdmin`.\n    /// @dev Dual-access: callable by the current minter admin OR the Owner. Reverts if\n    ///      `newMinterAdmin` is `address(0)` or is the current whitelist manager (enforces\n    ///      minter / whitelist manager key separation). Does not require a two-step confirmation.\n    /// @param newMinterAdmin Address to assign as the new minter admin.\n    function updateMinterAdmin(address newMinterAdmin) external virtual {\n        if (msg.sender != _getStablecoinV1Storage()._minterAdmin) {\n            _checkOwner();\n        }\n        if (newMinterAdmin == address(0)) {\n            revert InvalidMinterAdmin(address(0));\n        }\n        if (newMinterAdmin == whitelistManager()) {\n            revert MinterWhitelistManagerSeparationViolation(newMinterAdmin);\n        }\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        address oldMinterAdmin = $._minterAdmin;\n        $._minterAdmin = newMinterAdmin;\n        emit MinterAdminChanged(oldMinterAdmin, newMinterAdmin);\n    }\n\n    // ============ Internal Functions ============\n\n    /// @dev Core transfer logic shared by `transfer`, `transferFrom`, `transferWithAuthorization`,\n    ///      and `receiveWithAuthorization`. Reverts if `from` or `to` is `address(0)` or if `from`\n    ///      has insufficient balance.\n    /// @param from   Source address.\n    /// @param to     Destination address.\n    /// @param amount Number of tokens to move.\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        if (from == address(0)) {\n            revert InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert InvalidReceiver(address(0));\n        }\n\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        uint256 fromBalance = $._balances[from];\n        if (amount > fromBalance) {\n            revert InsufficientBalance(from, amount, fromBalance);\n        }\n\n        unchecked {\n            $._balances[from] = fromBalance - amount;\n            $._balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n    }\n\n    /// @dev Core approval logic shared by `approve`, `increaseAllowance`, `decreaseAllowance`,\n    ///      and `permit`. Reverts if `owner_` or `spender` is `address(0)`.\n    /// @param owner_  Token owner granting the allowance.\n    /// @param spender Address being approved.\n    /// @param amount  Allowance amount.\n    function _approve(address owner_, address spender, uint256 amount) internal virtual {\n        if (owner_ == address(0)) {\n            revert InvalidSender(address(0));\n        }\n        if (spender == address(0)) {\n            revert InvalidSpender(address(0));\n        }\n\n        _getStablecoinV1Storage()._allowances[owner_][spender] = amount;\n        emit Approval(owner_, spender, amount);\n    }\n\n    /// @dev Checks and decrements the allowance `owner_` has granted to `spender`. Skips the check\n    ///      if the allowance is `type(uint256).max` (unlimited). Reverts with `InsufficientAllowance`\n    ///      if `amount` exceeds the current allowance.\n    /// @param owner_   Token owner whose allowance is being spent.\n    /// @param spender  Address spending the allowance (typically `msg.sender`).\n    /// @param amount   Amount being spent.\n    function _spendAllowance(address owner_, address spender, uint256 amount) internal virtual {\n        StablecoinV1Storage storage $ = _getStablecoinV1Storage();\n        uint256 currentAllowance = $._allowances[owner_][spender];\n        if (currentAllowance != type(uint256).max) {\n            if (amount > currentAllowance) {\n                revert InsufficientAllowance(spender, amount, currentAllowance);\n            }\n            unchecked {\n                $._allowances[owner_][spender] = currentAllowance - amount;\n            }\n        }\n    }\n\n    /// @dev Sets the initial minter admin during `initialize`. Reverts if `initialMinterAdmin` is\n    ///      `address(0)`. Emits `MinterAdminChanged(address(0), initialMinterAdmin)`.\n    /// @param initialMinterAdmin Address to set as the first minter admin.\n    function _initializeMinterAdmin(address initialMinterAdmin) internal {\n        if (initialMinterAdmin == address(0)) {\n            revert InvalidMinterAdmin(address(0));\n        }\n        _getStablecoinV1Storage()._minterAdmin = initialMinterAdmin;\n        emit MinterAdminChanged(address(0), initialMinterAdmin);\n    }\n\n    /// @dev Bridges ERC-3009's typed-data hashing to the shared EIP-712 domain maintained by\n    ///      `EIP712Upgradeable`. Called by `_transferWithAuthorization`, `_receiveWithAuthorization`,\n    ///      and `_cancelAuthorization` in the `ERC3009Upgradeable` base.\n    /// @param structHash EIP-712 struct hash to wrap in the domain separator envelope.\n    /// @return Final EIP-712 digest ready for signature verification.\n    function _hashTypedDataV4ForAuth(bytes32 structHash) internal view override returns (bytes32) {\n        return _hashTypedDataV4(structHash);\n    }\n}\n","deployed_bytecode":"0x60a06040526004361015610011575f80fd5b5f3560e01c806306fdde03146135b9578063095ea7b3146135795780630f667dbf146128425780631171bda91461275d57806318160ddd146127345780631a895266146126ab57806323b872dd1461260157806326563b40146125cd57806329a204a4146125105780633092afd514612483578063313ce567146124445780633644e5151461242257806339509351146123bd5780633ac846b11461230f5780633edd1830146122415780633f4ba83a146121ad57806340c10f191461203c57806342966c6814611f38578063439531fd14611e805780634d1e049114611e4c5780634e44d95614611d1b5780634f1ef28614611b3a57806352d1902d14611ad4578063554bab3c14611a265780635a049a70146118ec5780635c975abb146118be57806364364d991461176957806368aaa60c1461168357806370a0823114611660578063715018a61461160357806379ba5097146115b75780637ecebe00146115605780638456cb59146114c657806384b0196e146111f25780638a6db9c3146111c65780638da5cb5b1461119257806395d89b41146110d55780639fd0506d146110a1578063a457c2d714611019578063a754d48f14610fe5578063a9059cbb14610f9a578063aa271e1a14610f75578063ad38bf2214610e94578063ad3cb1cc14610e4d578063af2c0f7a14610d5e578063b15c9ba314610c8e578063baf4961a14610c42578063bd10243014610c0e578063d505accf14610a90578063dd62ed3e14610a49578063dd7d7cd914610a15578063e30c3978146109e1578063e3ee160e14610923578063e5a6b10f14610841578063e94a0102146107ed578063e9b803021461070c578063ece11414146106d8578063ef55bec614610596578063f1a76fcc146104a5578063f2fde38b146103f4578063f9f92be414610336578063fe575a87146103055763ffa1ad74146102ce575f80fd5b34610301575f366003190112610301576102fd6102e9613834565b604051918291602083526020830190613676565b0390f35b5f80fd5b3461030157602036600319011261030157602060ff61032a61032561369a565b6138ff565b54166040519015158152f35b346103015760203660031901126103015761034f61369a565b5f51602061434d5f395f51905f52546001600160a01b031633036103e15760ff610378826138ff565b54166103c157610387816138ff565b805460ff191660011790556001600160a01b03167fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b8555f80a2005b63d40e1aa560e01b5f9081526001600160a01b0391909116600452602490fd5b636915b35d60e01b5f523360045260245ffd5b346103015760203660031901126103015761040d61369a565b5f51602061436d5f395f51905f52546001600160a01b039182169116811461049357610437613c0a565b5f51602061440d5f395f51905f5280546001600160a01b031916821790555f51602061428d5f395f51905f52546001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b63bbb67a9160e01b5f5260045260245ffd5b34610301576020366003190112610301576104be61369a565b5f51602061424d5f395f51905f5254906001600160a01b0382169033829003610589575b6001600160a01b0381169283156105765760ff6104ff859361396f565b5416610563575f51602061420d5f395f51905f52546001600160a01b03168214610563576001600160a01b031916175f51602061424d5f395f51905f52557f7a3269ff8fa4560f48f22fb82eac3bc7030aaa8ea8e65a40c2e7e8a61b2f0eb85f80a3005b50637f81d63960e01b5f5260045260245ffd5b630b351aeb60e31b5f525f60045260245ffd5b610591613c0a565b6104e2565b34610301576105a4366137d6565b9297946105b5979697929192613a94565b6105be86613abb565b6105c787613abb565b6001600160a01b038716943386036106c1579161068282846105f3610690989661068798968f8d613d27565b6040519060208201927fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8845260018060a01b038c169a8b604085015260608401528d608084015260a083015260c08201528c60e082015260e0815261065a610100826136c6565b519020610665613cc0565b6042916040519161190160f01b8352600283015260228201522090565b6140cb565b90929192614158565b6001600160a01b0316036106b2576106ab6106b09482613dac565b613b78565b005b630e479e9960e21b5f5260045ffd5b85631c5939f360e01b5f523360045260245260445ffd5b34610301575f366003190112610301575f51602061438d5f395f51905f52546040516001600160a01b039091168152602090f35b346103015761071a36613784565b5f51602061434d5f395f51905f52549091906001600160a01b031633036103e1575f5b82811061074657005b60ff61075e610325610759848787613a4f565b613a73565b5416156107c057806107796103256107596001948787613a4f565b60ff198154169055818060a01b03610795610759838787613a4f565b167f117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2fd88e2848137c4e5f80a20161073d565b6107cd9261075992613a4f565b631c16f44560e31b5f9081526001600160a01b0391909116600452602490fd5b346103015760403660031901126103015761080661369a565b60018060a01b03165f525f51602061432d5f395f51905f5260205260405f206024355f52602052602060ff60405f2054166040519015158152f35b34610301575f366003190112610301576040515f5f51602061422d5f395f51905f525461086d81613853565b80845290600181169081156108ff5750600114610895575b6102fd836102e9818503826136c6565b5f51602061422d5f395f51905f525f9081527f288ae9be002f4d7037c1e37319929bb444ccf1d30db5862cffac52ebe97a3c1b939250905b8082106108e5575090915081016020016102e9610885565b9192600181602092548385880101520191019092916108cd565b60ff191660208086019190915291151560051b840190910191506102e99050610885565b346103015761097261096761068761068261096c610690610943366137d6565b969b979a93929d91948e819b8593989f8f908f61095e613a94565b61096733613abb565b613abb565b8c613d27565b60405160208101917f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267835260018060a01b038b16998a604084015260018060a01b038d1660608401528d608084015260a083015260c08201528c60e082015260e0815261065a610100826136c6565b34610301575f366003190112610301575f51602061440d5f395f51905f52546040516001600160a01b039091168152602090f35b34610301575f366003190112610301575f51602061436d5f395f51905f52546040516001600160a01b039091168152602090f35b3461030157604036600319011261030157610a6261369a565b610a73610a6d6136b0565b91613937565b9060018060a01b03165f52602052602060405f2054604051908152f35b346103015760e036600319011261030157610aa961369a565b610ab16136b0565b60443590606435926084359360ff8516850361030157610acf613a94565b610ad833613abb565b610ae182613abb565b610aea83613abb565b804211610bfc5761068790610ba760018060a01b038416928392835f527ff2d07356d6de72b0c6efa1bb9141b750918118984fbc77dd4a5772f4f973b60060205260405f2054986040519060208201927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9845286604084015260018060a01b038a1660608401528a60808401528b60a084015260c083015260c08252610b9160e0836136c6565b61068260c4359360a43593519020610665613cc0565b6001600160a01b031603610bed576106b0946001915f527ff2d07356d6de72b0c6efa1bb9141b750918118984fbc77dd4a5772f4f973b6006020520160405f2055613aef565b638baa579f60e01b5f5260045ffd5b639e96b26f60e01b5f5260045260245ffd5b34610301575f366003190112610301575f51602061434d5f395f51905f52546040516001600160a01b039091168152602090f35b3461030157604036600319011261030157610c5b61369a565b610c6c610c666136b0565b916139df565b9060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b3461030157602036600319011261030157610ca761369a565b5f51602061436d5f395f51905f52546001600160a01b031633819003610d4b576001600160a01b038216918215610d38575f51602061428d5f395f51905f52546001600160a01b03168314610d2557610cff906138c5565b7faf8bd4c82bf7bbd16ed869ce74a697c4250f6017ea43c0c3566ea568799b300f5f80a3005b8263bbb67a9160e01b5f5260045260245ffd5b63509dedc160e11b5f525f60045260245ffd5b63ca8f130560e01b5f523360045260245ffd5b3461030157604036600319011261030157610d7761369a565b610d7f6136b0565b5f51602061424d5f395f51905f52546001600160a01b03163303610e3a57610da6826139df565b60018060a01b0382165f5260205260ff60405f20541615610e1657610dca826139df565b6001600160a01b039182165f81815260209290925260408220805460ff1916905592909116907fd9b8e07464bfc8278ae9c11d5ab83d05664fdbc7cb504f29a6577196e5cd3f5b9080a3005b63b9e2192b60e01b5f9081526001600160a01b039283166004529116602452604490fd5b63726e74a560e11b5f523360045260245ffd5b34610301575f366003190112610301576102fd604051610e6e6040826136c6565b60058152640352e302e360dc1b6020820152604051918291602083526020830190613676565b3461030157602036600319011261030157610ead61369a565b5f51602061434d5f395f51905f5254906001600160a01b0382169033829003610f68575b6001600160a01b0316918215610f55575f5160206141cd5f395f51905f52548391906001600160a01b03168214610f42576001600160a01b031916175f51602061434d5f395f51905f52557fa064e5d81fc677f8ce7876cf06e8772564e5e6813c8a33a0d04c748330b7b6195f80a3005b506325322c3b60e01b5f5260045260245ffd5b6313e9d38960e21b5f525f60045260245ffd5b610f70613c0a565b610ed1565b3461030157602036600319011261030157602060ff61032a610f9561369a565b61396f565b3461030157604036600319011261030157610fda610fb661369a565b610fbe613a94565b610fc733613abb565b610fd081613abb565b6024359033613b78565b602060405160018152f35b34610301575f366003190112610301575f51602061420d5f395f51905f52546040516001600160a01b039091168152602090f35b346103015760403660031901126103015761103261369a565b6024359061103e613a94565b61104733613abb565b61105081613abb565b61105933613937565b60018060a01b0382165f5260205260405f20549182811161108057610fda92039033613aef565b90630c95cf2760e11b5f5260018060a01b031660045260245260445260645ffd5b34610301575f366003190112610301575f5160206142cd5f395f51905f52546040516001600160a01b039091168152602090f35b34610301575f366003190112610301576040515f5f5160206141ed5f395f51905f525461110181613853565b80845290600181169081156108ff5750600114611128576102fd836102e9818503826136c6565b5f5160206141ed5f395f51905f525f9081527f15f132eae2669987333fe6861d41e121384a27961b06b42f01e61e328c3a88ac939250905b808210611178575090915081016020016102e9610885565b919260018160209254838588010152019101909291611160565b34610301575f366003190112610301575f51602061428d5f395f51905f52546040516001600160a01b039091168152602090f35b346103015760203660031901126103015760206111e96111e461369a565b6139a7565b54604051908152f35b34610301575f366003190112610301577fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10054158061149d575b15611460576040515f51602061426d5f395f51905f5254815f61124d83613853565b808352926001811690811561144157506001146113d6575b611271925003826136c6565b6040515f5160206142ad5f395f51905f5254815f61128e83613853565b80835292600181169081156113b7575060011461134c575b6112b9919250926112f0949303826136c6565b60206112fe604051926112cc83856136c6565b5f84525f368137604051958695600f60f81b875260e08588015260e0870190613676565b908582036040870152613676565b4660608501523060808501525f60a085015283810360c08501528180845192838152019301915f5b82811061133557505050500390f35b835185528695509381019392810192600101611326565b505f5160206142ad5f395f51905f525f90815290917f5f9ce34815f8e11431c7bb75a8e6886a91478f7ffc1dbb0a98dc240fddd76b755b81831061139b5750509060206112b9928201016112a6565b6020919350806001915483858801015201910190918392611383565b602092506112b994915060ff191682840152151560051b8201016112a6565b505f51602061426d5f395f51905f525f90815290917f42ad5d3e1f2e6e70edcf6d991b8a3023d3fca8047a131592f9edb9fd9b89d57d5b81831061142557505090602061127192820101611265565b602091935080600191548385880101520191019091839261140d565b6020925061127194915060ff191682840152151560051b820101611265565b60405162461bcd60e51b81526020600482015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b6044820152606490fd5b507fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d101541561122b565b34610301575f366003190112610301575f5160206142cd5f395f51905f52546001600160a01b0316330361154d576114fc613a94565b600160ff195f5160206143cd5f395f51905f525416175f5160206143cd5f395f51905f52557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b6310351a3760e11b5f523360045260245ffd5b34610301576020366003190112610301576001600160a01b0361158161369a565b165f527ff2d07356d6de72b0c6efa1bb9141b750918118984fbc77dd4a5772f4f973b600602052602060405f2054604051908152f35b34610301575f366003190112610301575f51602061440d5f395f51905f5254336001600160a01b03909116036115f0576106b033613c2a565b63118cdaa760e01b5f523360045260245ffd5b34610301575f3660031901126103015761161b613c0a565b60405162461bcd60e51b815260206004820152601a60248201527f72656e6f756e63654f776e6572736869702064697361626c65640000000000006044820152606490fd5b346103015760203660031901126103015760206111e961167e61369a565b613a17565b346103015760403660031901126103015761169c61369a565b6116a46136b0565b5f51602061424d5f395f51905f52546001600160a01b03163303610e3a576001600160a01b0316908115611756576116db816139df565b825f5260205260ff60405f205416611739576116f6816139df565b825f5260205260405f20600160ff1982541617905560018060a01b03167f796810d39a74ebd8491dbccd55afa54d9da820bd34ae02222e72b9729c80030a5f80a3005b63022b098760e01b5f5260018060a01b031660045260245260445ffd5b6340b9281760e01b5f525f60045260245ffd5b346103015760803660031901126103015761178261369a565b61178a6136b0565b5f5160206141cd5f395f51905f5254604435906001600160a01b031633036118ab576117b582613abb565b6001600160a01b03831691821561189c576001600160a01b03811693841561188d5760ff6117e2826138ff565b54161561187a576117f281613a17565b5480841161186057602092849261181c5f5160206143ad5f395f51905f5296611822940391613a17565b55613a17565b81815401905560405181815285857fb610dacff924ead5b27fc940d53d2416b6f4fc23529c92255f0f74f710364c598560643594a4604051908152a3005b8385633002359160e11b5f5260045260245260445260645ffd5b836302106dfd60e21b5f5260045260245ffd5b637f1224e360e01b5f5260045ffd5b6363942aad60e11b5f5260045ffd5b6327dc49e960e01b5f523360045260245ffd5b34610301575f36600319011261030157602060ff5f5160206143cd5f395f51905f5254166040519015158152f35b346103015760a03660031901126103015761190561369a565b602435906044359060ff821682036103015760018060a01b03168091815f525f51602061432d5f395f51905f5260205260405f20845f5260205260ff60405f205416611a0f576106876119ae9160405160208101917f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a15974298352856040830152876060830152606082526119986080836136c6565b6106826084359360643593519020610665613cc0565b6001600160a01b0316036106b257805f525f51602061432d5f395f51905f5260205260405f20825f5260205260405f20600160ff198254161790557f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d815f80a3005b505063d309466d60e01b5f5260045260245260445ffd5b3461030157602036600319011261030157611a3f61369a565b5f5160206142cd5f395f51905f5254906001600160a01b0382169033829003611ac7575b6001600160a01b0316918215611ab4576001600160a01b03191682175f5160206142cd5f395f51905f52557f95bb211a5a393c4d30c3edc9a745825fba4e6ad3e3bb949e6bf8ccdfe431a8115f80a3005b63e2a08e5d60e01b5f525f60045260245ffd5b611acf613c0a565b611a63565b34610301575f366003190112610301577f000000000000000000000000ba161409749ae95e9bbc1cf3a2dd3fe3e0af1d5e6001600160a01b03163003611b2b5760206040515f5160206142ed5f395f51905f528152f35b63703e46dd60e11b5f5260045ffd5b604036600319011261030157611b4e61369a565b6024356001600160401b038111610301573660238201121561030157611b7e9036906024816004013591016136e7565b906001600160a01b037f000000000000000000000000ba161409749ae95e9bbc1cf3a2dd3fe3e0af1d5e16308114908115611cf9575b50611b2b575f51602061436d5f395f51905f52546001600160a01b03163303610d4b576040516352d1902d60e01b81526001600160a01b0382169290602081600481875afa5f9181611cc5575b50611c195783634c9c8ce360e01b5f5260045260245ffd5b805f5160206142ed5f395f51905f52859203611cb35750823b15611ca1575f5160206142ed5f395f51905f5280546001600160a01b031916821790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a2805115611c89576106b09161403f565b505034611c9257005b63b398979f60e01b5f5260045ffd5b634c9c8ce360e01b5f5260045260245ffd5b632a87526960e21b5f5260045260245ffd5b9091506020813d602011611cf1575b81611ce1602093836136c6565b8101031261030157519085611c01565b3d9150611cd4565b5f5160206142ed5f395f51905f52546001600160a01b03161415905083611bb4565b3461030157604036600319011261030157611d3461369a565b5f51602061420d5f395f51905f5254602435906001600160a01b03163303611e3957611d5f82613abb565b5f51602061424d5f395f51905f52546001600160a01b038381169391168314611e2657611d8b816139a7565b54611e135760ff611d9b8261396f565b541680611e0b575b611dfc57817f46980fca912ef9bcdbd36877427b6b90e860769f604e89c0e67720cece530d2092611de983611dd960209561396f565b805460ff191660011790556139a7565b55604051908152a2602060405160018152f35b630cd4389160e31b5f5260045ffd5b508115611da3565b826349acafd360e11b5f5260045260245ffd5b82637f81d63960e01b5f5260045260245ffd5b63013f2c4b60e31b5f523360045260245ffd5b34610301575f366003190112610301575f5160206141cd5f395f51905f52546040516001600160a01b039091168152602090f35b3461030157602036600319011261030157611e9961369a565b5f51602061420d5f395f51905f52546001600160a01b031633819003611f2b575b6001600160a01b038216918215611f18575f51602061424d5f395f51905f52546001600160a01b03168314611e2657611ef29061388b565b7f8962ea348af57ce96c81c2b5a27a6bef5e441d8cea3163040af72359c39892c55f80a3005b63d1671ef760e01b5f525f60045260245ffd5b611f33613c0a565b611eba565b3461030157602036600319011261030157600435611f54613a94565b60ff611f5f3361396f565b54161561202957611f6f33613abb565b611f7833613a17565b549081811161201457809103611f8d33613a17565b555f51602061442d5f395f51905f525490808203918211612000575f915f51602061442d5f395f51905f52556040518181527fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca560203392a26040519081525f5160206143ad5f395f51905f5260203392a3005b634e487b7160e01b5f52601160045260245ffd5b634da88e2960e11b5f5260045260245260445ffd5b631b0e18f960e11b5f523360045260245ffd5b346103015760403660031901126103015761205561369a565b602435612060613a94565b60ff61206b3361396f565b5416156120295761207b33613abb565b61208482613abb565b61208d336139df565b60018060a01b0383165f5260205260ff60405f20541615612188578015612179576120b7336139a7565b5491828211612163575f5160206143ad5f395f51905f5260205f928486036120de336139a7565b556120f7855f51602061442d5f395f51905f5254613a87565b5f51602061442d5f395f51905f525561210f81613a17565b61211a868254613a87565b905560018060a01b031693846040518281527fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8843392a3604051908152a3602060405160018152f35b50633b9b8b9160e01b5f5260045260245260445ffd5b63199f5a0360e31b5f5260045ffd5b5063b9e2192b60e01b5f908152336004526001600160a01b0391909116602452604490fd5b34610301575f366003190112610301575f5160206142cd5f395f51905f52546001600160a01b0316330361154d575f5160206143cd5f395f51905f525460ff8116156122325760ff19165f5160206143cd5f395f51905f52557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b638dfc202b60e01b5f5260045ffd5b346103015760203660031901126103015761225a61369a565b5f5160206141cd5f395f51905f5254906001600160a01b0382169033829003612302575b6001600160a01b03169182156122ef575f51602061434d5f395f51905f52548391906001600160a01b03168214610f42576001600160a01b031916175f5160206141cd5f395f51905f52557f39938732571820664f4f16cc78c58dc4d8968b04ba087d90ca7fc21d1a7197e05f80a3005b63f997406160e01b5f525f60045260245ffd5b61230a613c0a565b61227e565b346103015760203660031901126103015761232861369a565b5f51602061438d5f395f51905f5254906001600160a01b03821690338290036123b0575b6001600160a01b031691821561239d576001600160a01b03191682175f51602061438d5f395f51905f52557fa67240fef6eef9b3358555115aabceb0db164959419099fc80f33a91a31b29595f80a3005b63ecf8b9af60e01b5f525f60045260245ffd5b6123b8613c0a565b61234c565b3461030157604036600319011261030157610fda6123d961369a565b6123e1613a94565b6123ea33613abb565b6123f381613abb565b6123fc33613937565b60018060a01b0382165f5260205261241b60405f206024359054613a87565b9033613aef565b34610301575f36600319011261030157602061243c613cc0565b604051908152f35b34610301575f36600319011261030157602060ff7f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9035416604051908152f35b346103015760203660031901126103015761249c61369a565b5f51602061420d5f395f51905f52546001600160a01b03163303611e3957806124c660209261396f565b805460ff191690555f6124d8826139a7565b55604051906001600160a01b03167fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb666925f80a260018152f35b346103015761251e36613784565b5f51602061434d5f395f51905f52549091906001600160a01b031633036103e1575f5b82811061254a57005b60ff61255d610325610759848787613a4f565b54166125c057806125776103256107596001948787613a4f565b8260ff19825416179055818060a01b03612595610759838787613a4f565b167fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b8555f80a201612541565b6103c19261075992613a4f565b34610301575f366003190112610301575f51602061424d5f395f51905f52546040516001600160a01b039091168152602090f35b346103015761260f3661374a565b90612618613a94565b61262133613abb565b61262a83613abb565b61263381613abb565b61263c83613937565b335f90815260209190915260409020549260018401612660575b610fda9350613b78565b83831161269057610fda9361267482613937565b60018060a01b0333165f526020528360405f2091039055612656565b5050630c95cf2760e11b5f523360045260245260445260645ffd5b34610301576020366003190112610301576126c461369a565b5f51602061434d5f395f51905f52546001600160a01b031633036103e15760ff6126ed826138ff565b5416156107cd576126fd816138ff565b805460ff191690556001600160a01b03167f117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2fd88e2848137c4e5f80a2005b34610301575f3660031901126103015760205f51602061442d5f395f51905f5254604051908152f35b346103015761276b3661374a565b5f51602061438d5f395f51905f52549092906001600160a01b0316330361282f5760018060a01b03166040519163a9059cbb60e01b5f5260018060a01b031692836004528060245260205f60448180865af160015f5114811615612810575b83604052156127fd5782527f722e05d96eeeed6120084dc2ca39d977940066b70f6b70f3c4a575c5269a5ec760203093a4005b50635274afe760e01b5f5260045260245ffd5b600181151661282657823b15153d1516166127ca565b833d5f823e3d90fd5b63ac45665160e01b5f523360045260245ffd5b3461030157610180366003190112610301576004356001600160401b0381116103015761287390369060040161372c565b6024356001600160401b0381116103015761289290369060040161372c565b6044356001600160401b038111610301576128b190369060040161372c565b916064359260ff8416840361030157608435926001600160a01b038416918285036103015760a4356001600160a01b03811696908790036103015760c4356001600160a01b038116908190036103015760e4356001600160a01b0381169081900361030157610104356001600160a01b038116929083900361030157610124356001600160a01b0381169590949086860361030157610144356001600160a01b038116989089900361030157610164356001600160a01b0381169c909b908d8d03610301575f5160206143ed5f395f51905f525460ff8160401c16156080526001600160401b0381161580613570575b60016001600160401b038316149081613566575b15908161355d575b5061354e5767ffffffffffffffff1981166001175f5160206143ed5f395f51905f5255608051613522575b506129f1613c95565b6129f9613c95565b8b1561350f57612a0890613c2a565b612a10613c95565b612a18613c95565b612a20613c95565b612a28613c95565b612a30613c95565b612a38613c95565b612a40613c95565b612a48613c95565b612a50613c95565b612a58613c95565b612a60613834565b612a68613c95565b612a70613c95565b612a78613c95565b81516001600160401b0381116130ba57612a9f5f51602061426d5f395f51905f5254613853565b601f8111613495575b50806020601f8211600114613419575f9161340e575b508160011b915f199060031b1c1916175f51602061426d5f395f51905f52555b8051906001600160401b0382116130ba578190612b085f5160206142ad5f395f51905f5254613853565b601f811161338c575b50602090601f831160011461330e575f92613303575b50508160011b915f199060031b1c1916175f5160206142ad5f395f51905f52555b5f7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100555f7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10155612b96613c95565b612b9e613c95565b612ba6613c95565b8051906001600160401b0382116130ba578190612bd05f51602061430d5f395f51905f5254613853565b601f8111613280575b50602090601f83116001146131e4575f926131d9575b50508160011b915f199060031b1c1916175f51602061430d5f395f51905f52555b8051906001600160401b0382116130ba578190612c3a5f5160206141ed5f395f51905f5254613853565b601f8111613157575b50602090601f83116001146130d9575f926130ce575b50508160011b915f199060031b1c1916175f5160206141ed5f395f51905f52555b8051906001600160401b0382116130ba57612ca25f51602061422d5f395f51905f5254613853565b601f8111613040575b50602090601f8311600114612fc05760ff9392915f9183612fb5575b50508160011b915f199060031b1c1916175f51602061422d5f395f51905f52555b1660ff197f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9035416177f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf90355858514612fa257828114612f90578915611ab4575f5160206142cd5f395f51905f5280546001600160a01b0319168b179055604051995f7f95bb211a5a393c4d30c3edc9a745825fba4e6ad3e3bb949e6bf8ccdfe431a8118180a38015610f55575f51602061434d5f395f51905f5280546001600160a01b031916821790555f7fa064e5d81fc677f8ce7876cf06e8772564e5e6813c8a33a0d04c748330b7b6198180a3801561239d575f51602061438d5f395f51905f5280546001600160a01b031916821790555f7fa67240fef6eef9b3358555115aabceb0db164959419099fc80f33a91a31b29598180a380156122ef575f5160206141cd5f395f51905f5280546001600160a01b031916821790555f7f39938732571820664f4f16cc78c58dc4d8968b04ba087d90ca7fc21d1a7197e08180a38115611f1857612e779061388b565b5f7f8962ea348af57ce96c81c2b5a27a6bef5e441d8cea3163040af72359c39892c58180a38015610576575f51602061424d5f395f51905f5280546001600160a01b031916821790555f7f7a3269ff8fa4560f48f22fb82eac3bc7030aaa8ea8e65a40c2e7e8a61b2f0eb88180a38215610d38578214612f7d57612efa906138c5565b5f7faf8bd4c82bf7bbd16ed869ce74a697c4250f6017ea43c0c3566ea568799b300f8180a3608051612f2857005b60207fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29168ff0000000000000000195f5160206143ed5f395f51905f5254165f5160206143ed5f395f51905f525560018152a1005b5063bbb67a9160e01b5f5260045260245ffd5b6325322c3b60e01b5f5260045260245ffd5b84637f81d63960e01b5f5260045260245ffd5b015190508e80612cc7565b90601f198316915f51602061422d5f395f51905f525f52815f20925f5b818110613028575091600193918560ff97969410613010575b505050811b015f51602061422d5f395f51905f5255612ce8565b01515f1960f88460031b161c191690558e8080612ff6565b92936020600181928786015181550195019301612fdd565b82811115612cab575f51602061422d5f395f51905f525f52601f830160051c7f288ae9be002f4d7037c1e37319929bb444ccf1d30db5862cffac52ebe97a3c1b602085106130b2575b81601f9101920160051c03905f5b8281106130a5575050612cab565b5f82820155600101613097565b5f9150613089565b634e487b7160e01b5f52604160045260245ffd5b015190508e80612c59565b5f5160206141ed5f395f51905f525f9081528281209350601f198516905b81811061313f5750908460019594939210613127575b505050811b015f5160206141ed5f395f51905f5255612c7a565b01515f1960f88460031b161c191690558e808061310d565b929360206001819287860151815501950193016130f7565b82811115612c43575f5160206141ed5f395f51905f525f52909150601f830160051c7f15f132eae2669987333fe6861d41e121384a27961b06b42f01e61e328c3a88ac602085106131d1575b849392601f0160051c82900391015f5b8281106131c1575050612c43565b5f818301558594506001016131b3565b5f91506131a3565b015190508f80612bef565b5f51602061430d5f395f51905f525f9081527f77770a7f003ae1b820fc3fe87db1164fb4c72dab0f11092c302d78e36ee68e159350601f198516905b8181106132685750908460019594939210613250575b505050811b015f51602061430d5f395f51905f5255612c10565b01515f1960f88460031b161c191690558f8080613236565b92936020600181928786015181550195019301613220565b82811115612bd9579091505f51602061430d5f395f51905f525f52601f830160051c90602084106132fb575b9080601f8594930160051c03905f5b8281106132c9575050612bd9565b5f8183017f77770a7f003ae1b820fc3fe87db1164fb4c72dab0f11092c302d78e36ee68e1501558594506001016132bb565b5f91506132ac565b015190505f80612b27565b5f5160206142ad5f395f51905f525f9081528281209350601f198516905b818110613374575090846001959493921061335c575b505050811b015f5160206142ad5f395f51905f5255612b48565b01515f1960f88460031b161c191690555f8080613342565b9293602060018192878601518155019501930161332c565b82811115612b11575f5160206142ad5f395f51905f525f52909150601f830160051c7f5f9ce34815f8e11431c7bb75a8e6886a91478f7ffc1dbb0a98dc240fddd76b7560208510613406575b849392601f0160051c82900391015f5b8281106133f6575050612b11565b5f818301558594506001016133e8565b5f91506133d8565b90508301515f612abe565b5f51602061426d5f395f51905f525f9081528181209250601f198416905b81811061347d57509083600194939210613465575b5050811b015f51602061426d5f395f51905f5255612ade565b8501515f1960f88460031b161c191690555f8061344c565b9192602060018192868a015181550194019201613437565b81811115612aa8575f51602061426d5f395f51905f525f52601f820160051c7f42ad5d3e1f2e6e70edcf6d991b8a3023d3fca8047a131592f9edb9fd9b89d57d60208410613507575b81601f9101920160051c03905f5b8281106134fa575050612aa8565b5f828201556001016134ec565b5f91506134de565b631e4fbdf760e01b5f525f60045260245ffd5b68ffffffffffffffffff191668010000000000000001175f5160206143ed5f395f51905f52558f6129e8565b63f92ee8a960e01b5f5260045ffd5b9050155f6129bd565b303b1591506129b5565b506080516129a1565b3461030157604036600319011261030157610fda61359561369a565b61359d613a94565b6135a633613abb565b6135af81613abb565b6024359033613aef565b34610301575f366003190112610301576040515f5f51602061430d5f395f51905f52546135e581613853565b80845290600181169081156108ff575060011461360c576102fd836102e9818503826136c6565b5f51602061430d5f395f51905f525f9081527f77770a7f003ae1b820fc3fe87db1164fb4c72dab0f11092c302d78e36ee68e15939250905b80821061365c575090915081016020016102e9610885565b919260018160209254838588010152019101909291613644565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361030157565b602435906001600160a01b038216820361030157565b90601f801991011681019081106001600160401b038211176130ba57604052565b9291926001600160401b0382116130ba5760405191613710601f8201601f1916602001846136c6565b829481845281830111610301578281602093845f960137010152565b9080601f8301121561030157816020613747933591016136e7565b90565b6060906003190112610301576004356001600160a01b038116810361030157906024356001600160a01b0381168103610301579060443590565b906020600319830112610301576004356001600160401b0381116103015782602382011215610301578060040135926001600160401b0384116103015760248460051b83010111610301576024019190565b610120906003190112610301576004356001600160a01b038116810361030157906024356001600160a01b0381168103610301579060443590606435906084359060a4359060c43560ff81168103610301579060e435906101043590565b604051906138436040836136c6565b60018252603160f81b6020830152565b90600182811c92168015613881575b602083101461386d57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691613862565b60018060a01b03166bffffffffffffffffffffffff60a01b5f51602061420d5f395f51905f525416175f51602061420d5f395f51905f5255565b60018060a01b03166bffffffffffffffffffffffff60a01b5f51602061436d5f395f51905f525416175f51602061436d5f395f51905f5255565b6001600160a01b03165f9081527f47ed0176f22c22a784fdb48f2353dc4c94f71ba0c26201793c80bae6a2d59c016020526040902090565b6001600160a01b03165f9081527f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9066020526040902090565b6001600160a01b03165f9081527f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9086020526040902090565b6001600160a01b03165f9081527f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9096020526040902090565b6001600160a01b03165f9081527f907aa7cd286c6c1c6e0026cabd242a3a452cc166cb408ce6cfd4ee25c4cff7016020526040902090565b6001600160a01b03165f9081527f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9056020526040902090565b9190811015613a5f5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036103015790565b9190820180921161200057565b60ff5f5160206143cd5f395f51905f525416613aac57565b63d93c066560e01b5f5260045ffd5b60ff613ac6826138ff565b5416613acf5750565b63571f7b4960e01b5f9081526001600160a01b0391909116600452602490fd5b916001600160a01b038316918215613b65576001600160a01b0316928315613b52577f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591613b3e602092613937565b855f5282528060405f2055604051908152a3565b63270af7ed60e11b5f525f60045260245ffd5b6313053d9360e21b5f525f60045260245ffd5b916001600160a01b038316918215613b65576001600160a01b038116938415613bf757613ba481613a17565b54808411613bdd57602092849261181c5f5160206143ad5f395f51905f5296613bce940391613a17565b818154019055604051908152a3565b838563db42144d60e01b5f5260045260245260445260645ffd5b639cfea58360e01b5f525f60045260245ffd5b5f51602061428d5f395f51905f52546001600160a01b031633036115f057565b5f51602061440d5f395f51905f5280546001600160a01b03199081169091555f51602061428d5f395f51905f5280549182166001600160a01b0393841690811790915591167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b60ff5f5160206143ed5f395f51905f525460401c1615613cb157565b631afcd79f60e31b5f5260045ffd5b613cc8613e0a565b613cd0613f37565b6040519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8452604083015260608201524660808201523060a082015260a08152613d2160c0826136c6565b51902090565b9192909280421115613d9a575080421015613d88575060018060a01b0316805f525f51602061432d5f395f51905f5260205260405f20825f5260205260ff60405f205416613d73575050565b63d309466d60e01b5f5260045260245260445ffd5b633d91b05f60e01b5f5260045260245ffd5b637a4df07960e01b5f5260045260245ffd5b6001600160a01b03165f8181525f51602061432d5f395f51905f52602090815260408083208584529091528120805460ff191660011790557f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a59080a3565b6040515f51602061426d5f395f51905f5254905f81613e2884613853565b9182825260208201946001811690815f14613f1b5750600114613eb0575b613e52925003826136c6565b51908115613e5e572090565b50507fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100548015613e8b5790565b507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47090565b505f51602061426d5f395f51905f525f90815290917f42ad5d3e1f2e6e70edcf6d991b8a3023d3fca8047a131592f9edb9fd9b89d57d5b818310613eff575050906020613e5292820101613e46565b6020919350806001915483858801015201910190918392613ee7565b60ff1916865250613e5292151560051b82016020019050613e46565b6040515f5160206142ad5f395f51905f5254905f81613f5584613853565b9182825260208201946001811690815f146140235750600114613fb8575b613f7f925003826136c6565b51908115613f8b572090565b50507fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d101548015613e8b5790565b505f5160206142ad5f395f51905f525f90815290917f5f9ce34815f8e11431c7bb75a8e6886a91478f7ffc1dbb0a98dc240fddd76b755b818310614007575050906020613f7f92820101613f73565b6020919350806001915483858801015201910190918392613fef565b60ff1916865250613f7f92151560051b82016020019050613f73565b905f8091602081519101845af480806140b8575b156140735750506040513d81523d5f602083013e60203d82010160405290565b1561409857639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b3d156140a9576040513d5f823e3d90fd5b63d6bda27560e01b5f5260045ffd5b503d1515806140535750813b1515614053565b91907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841161414d579160209360809260ff5f9560405194855216868401526040830152606082015282805260015afa15614142575f516001600160a01b0381161561413857905f905f90565b505f906001905f90565b6040513d5f823e3d90fd5b5050505f9160039190565b60048110156141b8578061416a575050565b600181036141815763f645eedf60e01b5f5260045ffd5b6002810361419c575063fce698f760e01b5f5260045260245ffd5b6003146141a65750565b6335e2f38360e21b5f5260045260245ffd5b634e487b7160e01b5f52602160045260245ffdfea3fdb05258ab622e74a58362581a283149dca7a127254a327031149afbca31006c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9016c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9076c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf902907aa7cd286c6c1c6e0026cabd242a3a452cc166cb408ce6cfd4ee25c4cff700a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1029016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d103ebc802681d20b2ebc02da6ef85f073c76a0b069e63f16affec826bc9ee416e00360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9000cc3a6a7ed0ec31d88893e315a1f53bbfc40f20e80bd43bcdac1eb4625e9920047ed0176f22c22a784fdb48f2353dc4c94f71ba0c26201793c80bae6a2d59c006c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf90a54277b0927ea5af1a08341ee9f905cc2cd003dcc021c2710bcea482634e0df00ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c006c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf904a264697066735822122018caa518555309d8ce6410f87163fd552581e6ff55c650973b0fad751fdefed164736f6c63430008220033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"osaka","libraries":{},"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"":["*"],"*":["*"]}},"remappings":["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/"],"viaIR":true},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":null,"compiler_version":"v0.8.34+commit.80d5c536","is_verified_via_verifier_alliance":false,"verified_at":"2026-05-16T16:49:15.989336Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60a080604052346100c257306080525f5160206145495f395f51905f525460ff8160401c166100b3576002600160401b03196001600160401b03821601610060575b60405161448290816100c78239608051818181611ae60152611b890152f35b6001600160401b0319166001600160401b039081175f5160206145495f395f51905f525581527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a15f80610041565b63f92ee8a960e01b5f5260045ffd5b5f80fdfe60a06040526004361015610011575f80fd5b5f3560e01c806306fdde03146135b9578063095ea7b3146135795780630f667dbf146128425780631171bda91461275d57806318160ddd146127345780631a895266146126ab57806323b872dd1461260157806326563b40146125cd57806329a204a4146125105780633092afd514612483578063313ce567146124445780633644e5151461242257806339509351146123bd5780633ac846b11461230f5780633edd1830146122415780633f4ba83a146121ad57806340c10f191461203c57806342966c6814611f38578063439531fd14611e805780634d1e049114611e4c5780634e44d95614611d1b5780634f1ef28614611b3a57806352d1902d14611ad4578063554bab3c14611a265780635a049a70146118ec5780635c975abb146118be57806364364d991461176957806368aaa60c1461168357806370a0823114611660578063715018a61461160357806379ba5097146115b75780637ecebe00146115605780638456cb59146114c657806384b0196e146111f25780638a6db9c3146111c65780638da5cb5b1461119257806395d89b41146110d55780639fd0506d146110a1578063a457c2d714611019578063a754d48f14610fe5578063a9059cbb14610f9a578063aa271e1a14610f75578063ad38bf2214610e94578063ad3cb1cc14610e4d578063af2c0f7a14610d5e578063b15c9ba314610c8e578063baf4961a14610c42578063bd10243014610c0e578063d505accf14610a90578063dd62ed3e14610a49578063dd7d7cd914610a15578063e30c3978146109e1578063e3ee160e14610923578063e5a6b10f14610841578063e94a0102146107ed578063e9b803021461070c578063ece11414146106d8578063ef55bec614610596578063f1a76fcc146104a5578063f2fde38b146103f4578063f9f92be414610336578063fe575a87146103055763ffa1ad74146102ce575f80fd5b34610301575f366003190112610301576102fd6102e9613834565b604051918291602083526020830190613676565b0390f35b5f80fd5b3461030157602036600319011261030157602060ff61032a61032561369a565b6138ff565b54166040519015158152f35b346103015760203660031901126103015761034f61369a565b5f51602061434d5f395f51905f52546001600160a01b031633036103e15760ff610378826138ff565b54166103c157610387816138ff565b805460ff191660011790556001600160a01b03167fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b8555f80a2005b63d40e1aa560e01b5f9081526001600160a01b0391909116600452602490fd5b636915b35d60e01b5f523360045260245ffd5b346103015760203660031901126103015761040d61369a565b5f51602061436d5f395f51905f52546001600160a01b039182169116811461049357610437613c0a565b5f51602061440d5f395f51905f5280546001600160a01b031916821790555f51602061428d5f395f51905f52546001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b63bbb67a9160e01b5f5260045260245ffd5b34610301576020366003190112610301576104be61369a565b5f51602061424d5f395f51905f5254906001600160a01b0382169033829003610589575b6001600160a01b0381169283156105765760ff6104ff859361396f565b5416610563575f51602061420d5f395f51905f52546001600160a01b03168214610563576001600160a01b031916175f51602061424d5f395f51905f52557f7a3269ff8fa4560f48f22fb82eac3bc7030aaa8ea8e65a40c2e7e8a61b2f0eb85f80a3005b50637f81d63960e01b5f5260045260245ffd5b630b351aeb60e31b5f525f60045260245ffd5b610591613c0a565b6104e2565b34610301576105a4366137d6565b9297946105b5979697929192613a94565b6105be86613abb565b6105c787613abb565b6001600160a01b038716943386036106c1579161068282846105f3610690989661068798968f8d613d27565b6040519060208201927fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8845260018060a01b038c169a8b604085015260608401528d608084015260a083015260c08201528c60e082015260e0815261065a610100826136c6565b519020610665613cc0565b6042916040519161190160f01b8352600283015260228201522090565b6140cb565b90929192614158565b6001600160a01b0316036106b2576106ab6106b09482613dac565b613b78565b005b630e479e9960e21b5f5260045ffd5b85631c5939f360e01b5f523360045260245260445ffd5b34610301575f366003190112610301575f51602061438d5f395f51905f52546040516001600160a01b039091168152602090f35b346103015761071a36613784565b5f51602061434d5f395f51905f52549091906001600160a01b031633036103e1575f5b82811061074657005b60ff61075e610325610759848787613a4f565b613a73565b5416156107c057806107796103256107596001948787613a4f565b60ff198154169055818060a01b03610795610759838787613a4f565b167f117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2fd88e2848137c4e5f80a20161073d565b6107cd9261075992613a4f565b631c16f44560e31b5f9081526001600160a01b0391909116600452602490fd5b346103015760403660031901126103015761080661369a565b60018060a01b03165f525f51602061432d5f395f51905f5260205260405f206024355f52602052602060ff60405f2054166040519015158152f35b34610301575f366003190112610301576040515f5f51602061422d5f395f51905f525461086d81613853565b80845290600181169081156108ff5750600114610895575b6102fd836102e9818503826136c6565b5f51602061422d5f395f51905f525f9081527f288ae9be002f4d7037c1e37319929bb444ccf1d30db5862cffac52ebe97a3c1b939250905b8082106108e5575090915081016020016102e9610885565b9192600181602092548385880101520191019092916108cd565b60ff191660208086019190915291151560051b840190910191506102e99050610885565b346103015761097261096761068761068261096c610690610943366137d6565b969b979a93929d91948e819b8593989f8f908f61095e613a94565b61096733613abb565b613abb565b8c613d27565b60405160208101917f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267835260018060a01b038b16998a604084015260018060a01b038d1660608401528d608084015260a083015260c08201528c60e082015260e0815261065a610100826136c6565b34610301575f366003190112610301575f51602061440d5f395f51905f52546040516001600160a01b039091168152602090f35b34610301575f366003190112610301575f51602061436d5f395f51905f52546040516001600160a01b039091168152602090f35b3461030157604036600319011261030157610a6261369a565b610a73610a6d6136b0565b91613937565b9060018060a01b03165f52602052602060405f2054604051908152f35b346103015760e036600319011261030157610aa961369a565b610ab16136b0565b60443590606435926084359360ff8516850361030157610acf613a94565b610ad833613abb565b610ae182613abb565b610aea83613abb565b804211610bfc5761068790610ba760018060a01b038416928392835f527ff2d07356d6de72b0c6efa1bb9141b750918118984fbc77dd4a5772f4f973b60060205260405f2054986040519060208201927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9845286604084015260018060a01b038a1660608401528a60808401528b60a084015260c083015260c08252610b9160e0836136c6565b61068260c4359360a43593519020610665613cc0565b6001600160a01b031603610bed576106b0946001915f527ff2d07356d6de72b0c6efa1bb9141b750918118984fbc77dd4a5772f4f973b6006020520160405f2055613aef565b638baa579f60e01b5f5260045ffd5b639e96b26f60e01b5f5260045260245ffd5b34610301575f366003190112610301575f51602061434d5f395f51905f52546040516001600160a01b039091168152602090f35b3461030157604036600319011261030157610c5b61369a565b610c6c610c666136b0565b916139df565b9060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b3461030157602036600319011261030157610ca761369a565b5f51602061436d5f395f51905f52546001600160a01b031633819003610d4b576001600160a01b038216918215610d38575f51602061428d5f395f51905f52546001600160a01b03168314610d2557610cff906138c5565b7faf8bd4c82bf7bbd16ed869ce74a697c4250f6017ea43c0c3566ea568799b300f5f80a3005b8263bbb67a9160e01b5f5260045260245ffd5b63509dedc160e11b5f525f60045260245ffd5b63ca8f130560e01b5f523360045260245ffd5b3461030157604036600319011261030157610d7761369a565b610d7f6136b0565b5f51602061424d5f395f51905f52546001600160a01b03163303610e3a57610da6826139df565b60018060a01b0382165f5260205260ff60405f20541615610e1657610dca826139df565b6001600160a01b039182165f81815260209290925260408220805460ff1916905592909116907fd9b8e07464bfc8278ae9c11d5ab83d05664fdbc7cb504f29a6577196e5cd3f5b9080a3005b63b9e2192b60e01b5f9081526001600160a01b039283166004529116602452604490fd5b63726e74a560e11b5f523360045260245ffd5b34610301575f366003190112610301576102fd604051610e6e6040826136c6565b60058152640352e302e360dc1b6020820152604051918291602083526020830190613676565b3461030157602036600319011261030157610ead61369a565b5f51602061434d5f395f51905f5254906001600160a01b0382169033829003610f68575b6001600160a01b0316918215610f55575f5160206141cd5f395f51905f52548391906001600160a01b03168214610f42576001600160a01b031916175f51602061434d5f395f51905f52557fa064e5d81fc677f8ce7876cf06e8772564e5e6813c8a33a0d04c748330b7b6195f80a3005b506325322c3b60e01b5f5260045260245ffd5b6313e9d38960e21b5f525f60045260245ffd5b610f70613c0a565b610ed1565b3461030157602036600319011261030157602060ff61032a610f9561369a565b61396f565b3461030157604036600319011261030157610fda610fb661369a565b610fbe613a94565b610fc733613abb565b610fd081613abb565b6024359033613b78565b602060405160018152f35b34610301575f366003190112610301575f51602061420d5f395f51905f52546040516001600160a01b039091168152602090f35b346103015760403660031901126103015761103261369a565b6024359061103e613a94565b61104733613abb565b61105081613abb565b61105933613937565b60018060a01b0382165f5260205260405f20549182811161108057610fda92039033613aef565b90630c95cf2760e11b5f5260018060a01b031660045260245260445260645ffd5b34610301575f366003190112610301575f5160206142cd5f395f51905f52546040516001600160a01b039091168152602090f35b34610301575f366003190112610301576040515f5f5160206141ed5f395f51905f525461110181613853565b80845290600181169081156108ff5750600114611128576102fd836102e9818503826136c6565b5f5160206141ed5f395f51905f525f9081527f15f132eae2669987333fe6861d41e121384a27961b06b42f01e61e328c3a88ac939250905b808210611178575090915081016020016102e9610885565b919260018160209254838588010152019101909291611160565b34610301575f366003190112610301575f51602061428d5f395f51905f52546040516001600160a01b039091168152602090f35b346103015760203660031901126103015760206111e96111e461369a565b6139a7565b54604051908152f35b34610301575f366003190112610301577fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10054158061149d575b15611460576040515f51602061426d5f395f51905f5254815f61124d83613853565b808352926001811690811561144157506001146113d6575b611271925003826136c6565b6040515f5160206142ad5f395f51905f5254815f61128e83613853565b80835292600181169081156113b7575060011461134c575b6112b9919250926112f0949303826136c6565b60206112fe604051926112cc83856136c6565b5f84525f368137604051958695600f60f81b875260e08588015260e0870190613676565b908582036040870152613676565b4660608501523060808501525f60a085015283810360c08501528180845192838152019301915f5b82811061133557505050500390f35b835185528695509381019392810192600101611326565b505f5160206142ad5f395f51905f525f90815290917f5f9ce34815f8e11431c7bb75a8e6886a91478f7ffc1dbb0a98dc240fddd76b755b81831061139b5750509060206112b9928201016112a6565b6020919350806001915483858801015201910190918392611383565b602092506112b994915060ff191682840152151560051b8201016112a6565b505f51602061426d5f395f51905f525f90815290917f42ad5d3e1f2e6e70edcf6d991b8a3023d3fca8047a131592f9edb9fd9b89d57d5b81831061142557505090602061127192820101611265565b602091935080600191548385880101520191019091839261140d565b6020925061127194915060ff191682840152151560051b820101611265565b60405162461bcd60e51b81526020600482015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b6044820152606490fd5b507fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d101541561122b565b34610301575f366003190112610301575f5160206142cd5f395f51905f52546001600160a01b0316330361154d576114fc613a94565b600160ff195f5160206143cd5f395f51905f525416175f5160206143cd5f395f51905f52557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b6310351a3760e11b5f523360045260245ffd5b34610301576020366003190112610301576001600160a01b0361158161369a565b165f527ff2d07356d6de72b0c6efa1bb9141b750918118984fbc77dd4a5772f4f973b600602052602060405f2054604051908152f35b34610301575f366003190112610301575f51602061440d5f395f51905f5254336001600160a01b03909116036115f0576106b033613c2a565b63118cdaa760e01b5f523360045260245ffd5b34610301575f3660031901126103015761161b613c0a565b60405162461bcd60e51b815260206004820152601a60248201527f72656e6f756e63654f776e6572736869702064697361626c65640000000000006044820152606490fd5b346103015760203660031901126103015760206111e961167e61369a565b613a17565b346103015760403660031901126103015761169c61369a565b6116a46136b0565b5f51602061424d5f395f51905f52546001600160a01b03163303610e3a576001600160a01b0316908115611756576116db816139df565b825f5260205260ff60405f205416611739576116f6816139df565b825f5260205260405f20600160ff1982541617905560018060a01b03167f796810d39a74ebd8491dbccd55afa54d9da820bd34ae02222e72b9729c80030a5f80a3005b63022b098760e01b5f5260018060a01b031660045260245260445ffd5b6340b9281760e01b5f525f60045260245ffd5b346103015760803660031901126103015761178261369a565b61178a6136b0565b5f5160206141cd5f395f51905f5254604435906001600160a01b031633036118ab576117b582613abb565b6001600160a01b03831691821561189c576001600160a01b03811693841561188d5760ff6117e2826138ff565b54161561187a576117f281613a17565b5480841161186057602092849261181c5f5160206143ad5f395f51905f5296611822940391613a17565b55613a17565b81815401905560405181815285857fb610dacff924ead5b27fc940d53d2416b6f4fc23529c92255f0f74f710364c598560643594a4604051908152a3005b8385633002359160e11b5f5260045260245260445260645ffd5b836302106dfd60e21b5f5260045260245ffd5b637f1224e360e01b5f5260045ffd5b6363942aad60e11b5f5260045ffd5b6327dc49e960e01b5f523360045260245ffd5b34610301575f36600319011261030157602060ff5f5160206143cd5f395f51905f5254166040519015158152f35b346103015760a03660031901126103015761190561369a565b602435906044359060ff821682036103015760018060a01b03168091815f525f51602061432d5f395f51905f5260205260405f20845f5260205260ff60405f205416611a0f576106876119ae9160405160208101917f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a15974298352856040830152876060830152606082526119986080836136c6565b6106826084359360643593519020610665613cc0565b6001600160a01b0316036106b257805f525f51602061432d5f395f51905f5260205260405f20825f5260205260405f20600160ff198254161790557f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d815f80a3005b505063d309466d60e01b5f5260045260245260445ffd5b3461030157602036600319011261030157611a3f61369a565b5f5160206142cd5f395f51905f5254906001600160a01b0382169033829003611ac7575b6001600160a01b0316918215611ab4576001600160a01b03191682175f5160206142cd5f395f51905f52557f95bb211a5a393c4d30c3edc9a745825fba4e6ad3e3bb949e6bf8ccdfe431a8115f80a3005b63e2a08e5d60e01b5f525f60045260245ffd5b611acf613c0a565b611a63565b34610301575f366003190112610301577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163003611b2b5760206040515f5160206142ed5f395f51905f528152f35b63703e46dd60e11b5f5260045ffd5b604036600319011261030157611b4e61369a565b6024356001600160401b038111610301573660238201121561030157611b7e9036906024816004013591016136e7565b906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016308114908115611cf9575b50611b2b575f51602061436d5f395f51905f52546001600160a01b03163303610d4b576040516352d1902d60e01b81526001600160a01b0382169290602081600481875afa5f9181611cc5575b50611c195783634c9c8ce360e01b5f5260045260245ffd5b805f5160206142ed5f395f51905f52859203611cb35750823b15611ca1575f5160206142ed5f395f51905f5280546001600160a01b031916821790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a2805115611c89576106b09161403f565b505034611c9257005b63b398979f60e01b5f5260045ffd5b634c9c8ce360e01b5f5260045260245ffd5b632a87526960e21b5f5260045260245ffd5b9091506020813d602011611cf1575b81611ce1602093836136c6565b8101031261030157519085611c01565b3d9150611cd4565b5f5160206142ed5f395f51905f52546001600160a01b03161415905083611bb4565b3461030157604036600319011261030157611d3461369a565b5f51602061420d5f395f51905f5254602435906001600160a01b03163303611e3957611d5f82613abb565b5f51602061424d5f395f51905f52546001600160a01b038381169391168314611e2657611d8b816139a7565b54611e135760ff611d9b8261396f565b541680611e0b575b611dfc57817f46980fca912ef9bcdbd36877427b6b90e860769f604e89c0e67720cece530d2092611de983611dd960209561396f565b805460ff191660011790556139a7565b55604051908152a2602060405160018152f35b630cd4389160e31b5f5260045ffd5b508115611da3565b826349acafd360e11b5f5260045260245ffd5b82637f81d63960e01b5f5260045260245ffd5b63013f2c4b60e31b5f523360045260245ffd5b34610301575f366003190112610301575f5160206141cd5f395f51905f52546040516001600160a01b039091168152602090f35b3461030157602036600319011261030157611e9961369a565b5f51602061420d5f395f51905f52546001600160a01b031633819003611f2b575b6001600160a01b038216918215611f18575f51602061424d5f395f51905f52546001600160a01b03168314611e2657611ef29061388b565b7f8962ea348af57ce96c81c2b5a27a6bef5e441d8cea3163040af72359c39892c55f80a3005b63d1671ef760e01b5f525f60045260245ffd5b611f33613c0a565b611eba565b3461030157602036600319011261030157600435611f54613a94565b60ff611f5f3361396f565b54161561202957611f6f33613abb565b611f7833613a17565b549081811161201457809103611f8d33613a17565b555f51602061442d5f395f51905f525490808203918211612000575f915f51602061442d5f395f51905f52556040518181527fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca560203392a26040519081525f5160206143ad5f395f51905f5260203392a3005b634e487b7160e01b5f52601160045260245ffd5b634da88e2960e11b5f5260045260245260445ffd5b631b0e18f960e11b5f523360045260245ffd5b346103015760403660031901126103015761205561369a565b602435612060613a94565b60ff61206b3361396f565b5416156120295761207b33613abb565b61208482613abb565b61208d336139df565b60018060a01b0383165f5260205260ff60405f20541615612188578015612179576120b7336139a7565b5491828211612163575f5160206143ad5f395f51905f5260205f928486036120de336139a7565b556120f7855f51602061442d5f395f51905f5254613a87565b5f51602061442d5f395f51905f525561210f81613a17565b61211a868254613a87565b905560018060a01b031693846040518281527fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8843392a3604051908152a3602060405160018152f35b50633b9b8b9160e01b5f5260045260245260445ffd5b63199f5a0360e31b5f5260045ffd5b5063b9e2192b60e01b5f908152336004526001600160a01b0391909116602452604490fd5b34610301575f366003190112610301575f5160206142cd5f395f51905f52546001600160a01b0316330361154d575f5160206143cd5f395f51905f525460ff8116156122325760ff19165f5160206143cd5f395f51905f52557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b638dfc202b60e01b5f5260045ffd5b346103015760203660031901126103015761225a61369a565b5f5160206141cd5f395f51905f5254906001600160a01b0382169033829003612302575b6001600160a01b03169182156122ef575f51602061434d5f395f51905f52548391906001600160a01b03168214610f42576001600160a01b031916175f5160206141cd5f395f51905f52557f39938732571820664f4f16cc78c58dc4d8968b04ba087d90ca7fc21d1a7197e05f80a3005b63f997406160e01b5f525f60045260245ffd5b61230a613c0a565b61227e565b346103015760203660031901126103015761232861369a565b5f51602061438d5f395f51905f5254906001600160a01b03821690338290036123b0575b6001600160a01b031691821561239d576001600160a01b03191682175f51602061438d5f395f51905f52557fa67240fef6eef9b3358555115aabceb0db164959419099fc80f33a91a31b29595f80a3005b63ecf8b9af60e01b5f525f60045260245ffd5b6123b8613c0a565b61234c565b3461030157604036600319011261030157610fda6123d961369a565b6123e1613a94565b6123ea33613abb565b6123f381613abb565b6123fc33613937565b60018060a01b0382165f5260205261241b60405f206024359054613a87565b9033613aef565b34610301575f36600319011261030157602061243c613cc0565b604051908152f35b34610301575f36600319011261030157602060ff7f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9035416604051908152f35b346103015760203660031901126103015761249c61369a565b5f51602061420d5f395f51905f52546001600160a01b03163303611e3957806124c660209261396f565b805460ff191690555f6124d8826139a7565b55604051906001600160a01b03167fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb666925f80a260018152f35b346103015761251e36613784565b5f51602061434d5f395f51905f52549091906001600160a01b031633036103e1575f5b82811061254a57005b60ff61255d610325610759848787613a4f565b54166125c057806125776103256107596001948787613a4f565b8260ff19825416179055818060a01b03612595610759838787613a4f565b167fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b8555f80a201612541565b6103c19261075992613a4f565b34610301575f366003190112610301575f51602061424d5f395f51905f52546040516001600160a01b039091168152602090f35b346103015761260f3661374a565b90612618613a94565b61262133613abb565b61262a83613abb565b61263381613abb565b61263c83613937565b335f90815260209190915260409020549260018401612660575b610fda9350613b78565b83831161269057610fda9361267482613937565b60018060a01b0333165f526020528360405f2091039055612656565b5050630c95cf2760e11b5f523360045260245260445260645ffd5b34610301576020366003190112610301576126c461369a565b5f51602061434d5f395f51905f52546001600160a01b031633036103e15760ff6126ed826138ff565b5416156107cd576126fd816138ff565b805460ff191690556001600160a01b03167f117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2fd88e2848137c4e5f80a2005b34610301575f3660031901126103015760205f51602061442d5f395f51905f5254604051908152f35b346103015761276b3661374a565b5f51602061438d5f395f51905f52549092906001600160a01b0316330361282f5760018060a01b03166040519163a9059cbb60e01b5f5260018060a01b031692836004528060245260205f60448180865af160015f5114811615612810575b83604052156127fd5782527f722e05d96eeeed6120084dc2ca39d977940066b70f6b70f3c4a575c5269a5ec760203093a4005b50635274afe760e01b5f5260045260245ffd5b600181151661282657823b15153d1516166127ca565b833d5f823e3d90fd5b63ac45665160e01b5f523360045260245ffd5b3461030157610180366003190112610301576004356001600160401b0381116103015761287390369060040161372c565b6024356001600160401b0381116103015761289290369060040161372c565b6044356001600160401b038111610301576128b190369060040161372c565b916064359260ff8416840361030157608435926001600160a01b038416918285036103015760a4356001600160a01b03811696908790036103015760c4356001600160a01b038116908190036103015760e4356001600160a01b0381169081900361030157610104356001600160a01b038116929083900361030157610124356001600160a01b0381169590949086860361030157610144356001600160a01b038116989089900361030157610164356001600160a01b0381169c909b908d8d03610301575f5160206143ed5f395f51905f525460ff8160401c16156080526001600160401b0381161580613570575b60016001600160401b038316149081613566575b15908161355d575b5061354e5767ffffffffffffffff1981166001175f5160206143ed5f395f51905f5255608051613522575b506129f1613c95565b6129f9613c95565b8b1561350f57612a0890613c2a565b612a10613c95565b612a18613c95565b612a20613c95565b612a28613c95565b612a30613c95565b612a38613c95565b612a40613c95565b612a48613c95565b612a50613c95565b612a58613c95565b612a60613834565b612a68613c95565b612a70613c95565b612a78613c95565b81516001600160401b0381116130ba57612a9f5f51602061426d5f395f51905f5254613853565b601f8111613495575b50806020601f8211600114613419575f9161340e575b508160011b915f199060031b1c1916175f51602061426d5f395f51905f52555b8051906001600160401b0382116130ba578190612b085f5160206142ad5f395f51905f5254613853565b601f811161338c575b50602090601f831160011461330e575f92613303575b50508160011b915f199060031b1c1916175f5160206142ad5f395f51905f52555b5f7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100555f7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10155612b96613c95565b612b9e613c95565b612ba6613c95565b8051906001600160401b0382116130ba578190612bd05f51602061430d5f395f51905f5254613853565b601f8111613280575b50602090601f83116001146131e4575f926131d9575b50508160011b915f199060031b1c1916175f51602061430d5f395f51905f52555b8051906001600160401b0382116130ba578190612c3a5f5160206141ed5f395f51905f5254613853565b601f8111613157575b50602090601f83116001146130d9575f926130ce575b50508160011b915f199060031b1c1916175f5160206141ed5f395f51905f52555b8051906001600160401b0382116130ba57612ca25f51602061422d5f395f51905f5254613853565b601f8111613040575b50602090601f8311600114612fc05760ff9392915f9183612fb5575b50508160011b915f199060031b1c1916175f51602061422d5f395f51905f52555b1660ff197f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9035416177f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf90355858514612fa257828114612f90578915611ab4575f5160206142cd5f395f51905f5280546001600160a01b0319168b179055604051995f7f95bb211a5a393c4d30c3edc9a745825fba4e6ad3e3bb949e6bf8ccdfe431a8118180a38015610f55575f51602061434d5f395f51905f5280546001600160a01b031916821790555f7fa064e5d81fc677f8ce7876cf06e8772564e5e6813c8a33a0d04c748330b7b6198180a3801561239d575f51602061438d5f395f51905f5280546001600160a01b031916821790555f7fa67240fef6eef9b3358555115aabceb0db164959419099fc80f33a91a31b29598180a380156122ef575f5160206141cd5f395f51905f5280546001600160a01b031916821790555f7f39938732571820664f4f16cc78c58dc4d8968b04ba087d90ca7fc21d1a7197e08180a38115611f1857612e779061388b565b5f7f8962ea348af57ce96c81c2b5a27a6bef5e441d8cea3163040af72359c39892c58180a38015610576575f51602061424d5f395f51905f5280546001600160a01b031916821790555f7f7a3269ff8fa4560f48f22fb82eac3bc7030aaa8ea8e65a40c2e7e8a61b2f0eb88180a38215610d38578214612f7d57612efa906138c5565b5f7faf8bd4c82bf7bbd16ed869ce74a697c4250f6017ea43c0c3566ea568799b300f8180a3608051612f2857005b60207fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29168ff0000000000000000195f5160206143ed5f395f51905f5254165f5160206143ed5f395f51905f525560018152a1005b5063bbb67a9160e01b5f5260045260245ffd5b6325322c3b60e01b5f5260045260245ffd5b84637f81d63960e01b5f5260045260245ffd5b015190508e80612cc7565b90601f198316915f51602061422d5f395f51905f525f52815f20925f5b818110613028575091600193918560ff97969410613010575b505050811b015f51602061422d5f395f51905f5255612ce8565b01515f1960f88460031b161c191690558e8080612ff6565b92936020600181928786015181550195019301612fdd565b82811115612cab575f51602061422d5f395f51905f525f52601f830160051c7f288ae9be002f4d7037c1e37319929bb444ccf1d30db5862cffac52ebe97a3c1b602085106130b2575b81601f9101920160051c03905f5b8281106130a5575050612cab565b5f82820155600101613097565b5f9150613089565b634e487b7160e01b5f52604160045260245ffd5b015190508e80612c59565b5f5160206141ed5f395f51905f525f9081528281209350601f198516905b81811061313f5750908460019594939210613127575b505050811b015f5160206141ed5f395f51905f5255612c7a565b01515f1960f88460031b161c191690558e808061310d565b929360206001819287860151815501950193016130f7565b82811115612c43575f5160206141ed5f395f51905f525f52909150601f830160051c7f15f132eae2669987333fe6861d41e121384a27961b06b42f01e61e328c3a88ac602085106131d1575b849392601f0160051c82900391015f5b8281106131c1575050612c43565b5f818301558594506001016131b3565b5f91506131a3565b015190508f80612bef565b5f51602061430d5f395f51905f525f9081527f77770a7f003ae1b820fc3fe87db1164fb4c72dab0f11092c302d78e36ee68e159350601f198516905b8181106132685750908460019594939210613250575b505050811b015f51602061430d5f395f51905f5255612c10565b01515f1960f88460031b161c191690558f8080613236565b92936020600181928786015181550195019301613220565b82811115612bd9579091505f51602061430d5f395f51905f525f52601f830160051c90602084106132fb575b9080601f8594930160051c03905f5b8281106132c9575050612bd9565b5f8183017f77770a7f003ae1b820fc3fe87db1164fb4c72dab0f11092c302d78e36ee68e1501558594506001016132bb565b5f91506132ac565b015190505f80612b27565b5f5160206142ad5f395f51905f525f9081528281209350601f198516905b818110613374575090846001959493921061335c575b505050811b015f5160206142ad5f395f51905f5255612b48565b01515f1960f88460031b161c191690555f8080613342565b9293602060018192878601518155019501930161332c565b82811115612b11575f5160206142ad5f395f51905f525f52909150601f830160051c7f5f9ce34815f8e11431c7bb75a8e6886a91478f7ffc1dbb0a98dc240fddd76b7560208510613406575b849392601f0160051c82900391015f5b8281106133f6575050612b11565b5f818301558594506001016133e8565b5f91506133d8565b90508301515f612abe565b5f51602061426d5f395f51905f525f9081528181209250601f198416905b81811061347d57509083600194939210613465575b5050811b015f51602061426d5f395f51905f5255612ade565b8501515f1960f88460031b161c191690555f8061344c565b9192602060018192868a015181550194019201613437565b81811115612aa8575f51602061426d5f395f51905f525f52601f820160051c7f42ad5d3e1f2e6e70edcf6d991b8a3023d3fca8047a131592f9edb9fd9b89d57d60208410613507575b81601f9101920160051c03905f5b8281106134fa575050612aa8565b5f828201556001016134ec565b5f91506134de565b631e4fbdf760e01b5f525f60045260245ffd5b68ffffffffffffffffff191668010000000000000001175f5160206143ed5f395f51905f52558f6129e8565b63f92ee8a960e01b5f5260045ffd5b9050155f6129bd565b303b1591506129b5565b506080516129a1565b3461030157604036600319011261030157610fda61359561369a565b61359d613a94565b6135a633613abb565b6135af81613abb565b6024359033613aef565b34610301575f366003190112610301576040515f5f51602061430d5f395f51905f52546135e581613853565b80845290600181169081156108ff575060011461360c576102fd836102e9818503826136c6565b5f51602061430d5f395f51905f525f9081527f77770a7f003ae1b820fc3fe87db1164fb4c72dab0f11092c302d78e36ee68e15939250905b80821061365c575090915081016020016102e9610885565b919260018160209254838588010152019101909291613644565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361030157565b602435906001600160a01b038216820361030157565b90601f801991011681019081106001600160401b038211176130ba57604052565b9291926001600160401b0382116130ba5760405191613710601f8201601f1916602001846136c6565b829481845281830111610301578281602093845f960137010152565b9080601f8301121561030157816020613747933591016136e7565b90565b6060906003190112610301576004356001600160a01b038116810361030157906024356001600160a01b0381168103610301579060443590565b906020600319830112610301576004356001600160401b0381116103015782602382011215610301578060040135926001600160401b0384116103015760248460051b83010111610301576024019190565b610120906003190112610301576004356001600160a01b038116810361030157906024356001600160a01b0381168103610301579060443590606435906084359060a4359060c43560ff81168103610301579060e435906101043590565b604051906138436040836136c6565b60018252603160f81b6020830152565b90600182811c92168015613881575b602083101461386d57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691613862565b60018060a01b03166bffffffffffffffffffffffff60a01b5f51602061420d5f395f51905f525416175f51602061420d5f395f51905f5255565b60018060a01b03166bffffffffffffffffffffffff60a01b5f51602061436d5f395f51905f525416175f51602061436d5f395f51905f5255565b6001600160a01b03165f9081527f47ed0176f22c22a784fdb48f2353dc4c94f71ba0c26201793c80bae6a2d59c016020526040902090565b6001600160a01b03165f9081527f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9066020526040902090565b6001600160a01b03165f9081527f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9086020526040902090565b6001600160a01b03165f9081527f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9096020526040902090565b6001600160a01b03165f9081527f907aa7cd286c6c1c6e0026cabd242a3a452cc166cb408ce6cfd4ee25c4cff7016020526040902090565b6001600160a01b03165f9081527f6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9056020526040902090565b9190811015613a5f5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036103015790565b9190820180921161200057565b60ff5f5160206143cd5f395f51905f525416613aac57565b63d93c066560e01b5f5260045ffd5b60ff613ac6826138ff565b5416613acf5750565b63571f7b4960e01b5f9081526001600160a01b0391909116600452602490fd5b916001600160a01b038316918215613b65576001600160a01b0316928315613b52577f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591613b3e602092613937565b855f5282528060405f2055604051908152a3565b63270af7ed60e11b5f525f60045260245ffd5b6313053d9360e21b5f525f60045260245ffd5b916001600160a01b038316918215613b65576001600160a01b038116938415613bf757613ba481613a17565b54808411613bdd57602092849261181c5f5160206143ad5f395f51905f5296613bce940391613a17565b818154019055604051908152a3565b838563db42144d60e01b5f5260045260245260445260645ffd5b639cfea58360e01b5f525f60045260245ffd5b5f51602061428d5f395f51905f52546001600160a01b031633036115f057565b5f51602061440d5f395f51905f5280546001600160a01b03199081169091555f51602061428d5f395f51905f5280549182166001600160a01b0393841690811790915591167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b60ff5f5160206143ed5f395f51905f525460401c1615613cb157565b631afcd79f60e31b5f5260045ffd5b613cc8613e0a565b613cd0613f37565b6040519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8452604083015260608201524660808201523060a082015260a08152613d2160c0826136c6565b51902090565b9192909280421115613d9a575080421015613d88575060018060a01b0316805f525f51602061432d5f395f51905f5260205260405f20825f5260205260ff60405f205416613d73575050565b63d309466d60e01b5f5260045260245260445ffd5b633d91b05f60e01b5f5260045260245ffd5b637a4df07960e01b5f5260045260245ffd5b6001600160a01b03165f8181525f51602061432d5f395f51905f52602090815260408083208584529091528120805460ff191660011790557f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a59080a3565b6040515f51602061426d5f395f51905f5254905f81613e2884613853565b9182825260208201946001811690815f14613f1b5750600114613eb0575b613e52925003826136c6565b51908115613e5e572090565b50507fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100548015613e8b5790565b507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47090565b505f51602061426d5f395f51905f525f90815290917f42ad5d3e1f2e6e70edcf6d991b8a3023d3fca8047a131592f9edb9fd9b89d57d5b818310613eff575050906020613e5292820101613e46565b6020919350806001915483858801015201910190918392613ee7565b60ff1916865250613e5292151560051b82016020019050613e46565b6040515f5160206142ad5f395f51905f5254905f81613f5584613853565b9182825260208201946001811690815f146140235750600114613fb8575b613f7f925003826136c6565b51908115613f8b572090565b50507fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d101548015613e8b5790565b505f5160206142ad5f395f51905f525f90815290917f5f9ce34815f8e11431c7bb75a8e6886a91478f7ffc1dbb0a98dc240fddd76b755b818310614007575050906020613f7f92820101613f73565b6020919350806001915483858801015201910190918392613fef565b60ff1916865250613f7f92151560051b82016020019050613f73565b905f8091602081519101845af480806140b8575b156140735750506040513d81523d5f602083013e60203d82010160405290565b1561409857639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b3d156140a9576040513d5f823e3d90fd5b63d6bda27560e01b5f5260045ffd5b503d1515806140535750813b1515614053565b91907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841161414d579160209360809260ff5f9560405194855216868401526040830152606082015282805260015afa15614142575f516001600160a01b0381161561413857905f905f90565b505f906001905f90565b6040513d5f823e3d90fd5b5050505f9160039190565b60048110156141b8578061416a575050565b600181036141815763f645eedf60e01b5f5260045ffd5b6002810361419c575063fce698f760e01b5f5260045260245ffd5b6003146141a65750565b6335e2f38360e21b5f5260045260245ffd5b634e487b7160e01b5f52602160045260245ffdfea3fdb05258ab622e74a58362581a283149dca7a127254a327031149afbca31006c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9016c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9076c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf902907aa7cd286c6c1c6e0026cabd242a3a452cc166cb408ce6cfd4ee25c4cff700a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1029016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d103ebc802681d20b2ebc02da6ef85f073c76a0b069e63f16affec826bc9ee416e00360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf9000cc3a6a7ed0ec31d88893e315a1f53bbfc40f20e80bd43bcdac1eb4625e9920047ed0176f22c22a784fdb48f2353dc4c94f71ba0c26201793c80bae6a2d59c006c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf90a54277b0927ea5af1a08341ee9f905cc2cd003dcc021c2710bcea482634e0df00ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c006c184abdc3a902bd683a162844cbc212a3153de80685635cb008ee8049bbf904a264697066735822122018caa518555309d8ce6410f87163fd552581e6ff55c650973b0fad751fdefed164736f6c63430008220033f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00","name":"StablecoinV1","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":false,"language":"solidity","evm_version":"osaka","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev ERC-1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/math/Math.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Return the 512-bit addition of two uint256.\n     *\n     * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.\n     */\n    function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        assembly (\"memory-safe\") {\n            low := add(a, b)\n            high := lt(low, a)\n        }\n    }\n\n    /**\n     * @dev Return the 512-bit multiplication of two uint256.\n     *\n     * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.\n     */\n    function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n        // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n        // variables such that product = high * 2²⁵⁶ + low.\n        assembly (\"memory-safe\") {\n            let mm := mulmod(a, b, not(0))\n            low := mul(a, b)\n            high := sub(sub(mm, low), lt(mm, low))\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            success = c >= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a - b;\n            success = c <= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a * b;\n            assembly (\"memory-safe\") {\n                // Only true when the multiplication doesn't overflow\n                // (c / a == b) || (a == 0)\n                success := or(eq(div(c, a), b), iszero(a))\n            }\n            // equivalent to: success ? c : 0\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `DIV` opcode returns zero when the denominator is 0.\n                result := div(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `MOD` opcode returns zero when the denominator is 0.\n                result := mod(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryAdd(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.\n     */\n    function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {\n        (, uint256 result) = trySub(a, b);\n        return result;\n    }\n\n    /**\n     * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryMul(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `condition ? a : b`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `condition ? a : b`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (high == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return low / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= high) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [high low].\n            uint256 remainder;\n            assembly (\"memory-safe\") {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                high := sub(high, gt(remainder, low))\n                low := sub(low, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly (\"memory-safe\") {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [high low] by twos.\n                low := div(low, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from high into low.\n            low |= high * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high\n            // is no longer required.\n            result = low * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n            if (high >= 1 << n) {\n                Panic.panic(Panic.UNDER_OVERFLOW);\n            }\n            return (high << (256 - n)) | (low >> n);\n        }\n    }\n\n    /**\n     * @dev Calculates x * y >> n with full precision, following the selected rounding direction.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {\n        return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {\n        for (uint256 i = 0; i < byteArray.length; ++i) {\n            if (byteArray[i] != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // If upper 8 bits of 16-bit half set, add 8 to result\n        r |= SafeCast.toUint((x >> r) > 0xff) << 3;\n        // If upper 4 bits of 8-bit half set, add 4 to result\n        r |= SafeCast.toUint((x >> r) > 0xf) << 2;\n\n        // Shifts value right by the current result and use it as an index into this lookup table:\n        //\n        // | x (4 bits) |  index  | table[index] = MSB position |\n        // |------------|---------|-----------------------------|\n        // |    0000    |    0    |        table[0] = 0         |\n        // |    0001    |    1    |        table[1] = 0         |\n        // |    0010    |    2    |        table[2] = 1         |\n        // |    0011    |    3    |        table[3] = 1         |\n        // |    0100    |    4    |        table[4] = 2         |\n        // |    0101    |    5    |        table[5] = 2         |\n        // |    0110    |    6    |        table[6] = 2         |\n        // |    0111    |    7    |        table[7] = 2         |\n        // |    1000    |    8    |        table[8] = 3         |\n        // |    1001    |    9    |        table[9] = 3         |\n        // |    1010    |   10    |        table[10] = 3        |\n        // |    1011    |   11    |        table[11] = 3        |\n        // |    1100    |   12    |        table[12] = 3        |\n        // |    1101    |   13    |        table[13] = 3        |\n        // |    1110    |   14    |        table[14] = 3        |\n        // |    1111    |   15    |        table[15] = 3        |\n        //\n        // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes.\n        assembly (\"memory-safe\") {\n            r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8\n        return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n\n    /**\n     * @dev Counts the number of leading zero bits in a uint256.\n     */\n    function clz(uint256 x) internal pure returns (uint256) {\n        return ternary(x == 0, 256, 255 - log2(x));\n    }\n}\n"},{"file_path":"src/Pausable.sol","source_code":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.34;\n\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @title Pausable\n * @dev Extends OpenZeppelin Pausable with a designated pauser address (Upgradeable)\n */\nabstract contract Pausable is Initializable, PausableUpgradeable {\n    /// @custom:storage-location erc7201:jpysc.storage.JPYSCPausable\n    struct JPYSCPausableStorage {\n        address _pauser;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"jpysc.storage.JPYSCPausable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant JPYSC_PAUSABLE_STORAGE_LOCATION =\n        0xebc802681d20b2ebc02da6ef85f073c76a0b069e63f16affec826bc9ee416e00;\n\n    function _getJPYSCPausableStorage() private pure returns (JPYSCPausableStorage storage $) {\n        assembly {\n            $.slot := JPYSC_PAUSABLE_STORAGE_LOCATION\n        }\n    }\n\n    event PauserChanged(address indexed previousPauser, address indexed newPauser);\n\n    error NotPauser(address account);\n    error InvalidPauser(address pauser);\n\n    modifier onlyPauser() {\n        if (msg.sender != _getJPYSCPausableStorage()._pauser) {\n            revert NotPauser(msg.sender);\n        }\n        _;\n    }\n\n    function __JPYSCPausable_init() internal onlyInitializing {\n        __Pausable_init_unchained();\n    }\n\n    function pauser() public view returns (address) {\n        return _getJPYSCPausableStorage()._pauser;\n    }\n\n    function pause() external onlyPauser {\n        _pause();\n    }\n\n    function unpause() external onlyPauser {\n        _unpause();\n    }\n\n    function _setPauser(address newPauser) internal {\n        address oldPauser = _getJPYSCPausableStorage()._pauser;\n        _getJPYSCPausableStorage()._pauser = newPauser;\n        emit PauserChanged(oldPauser, newPauser);\n    }\n\n    function _initializePauser(address initialPauser) internal {\n        if (initialPauser == address(0)) {\n            revert InvalidPauser(address(0));\n        }\n        _getJPYSCPausableStorage()._pauser = initialPauser;\n        emit PauserChanged(address(0), initialPauser);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/EIP712Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.24;\n\nimport {MessageHashUtils} from \"@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol\";\nimport {IERC5267} from \"@openzeppelin/contracts/interfaces/IERC5267.sol\";\nimport {Initializable} from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP-712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose\n * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract\n * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to\n * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP-712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: The upgradeable version of this contract does not use an immutable cache and recomputes the domain separator\n * each time {_domainSeparatorV4} is called. That is cheaper than accessing a cached version in cold storage.\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267 {\n    bytes32 private constant TYPE_HASH =\n        keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.EIP712\n    struct EIP712Storage {\n        /// @custom:oz-renamed-from _HASHED_NAME\n        bytes32 _hashedName;\n        /// @custom:oz-renamed-from _HASHED_VERSION\n        bytes32 _hashedVersion;\n\n        string _name;\n        string _version;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.EIP712\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant EIP712StorageLocation = 0xa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100;\n\n    function _getEIP712Storage() private pure returns (EIP712Storage storage $) {\n        assembly {\n            $.slot := EIP712StorageLocation\n        }\n    }\n\n    /**\n     * @dev Initializes the domain separator and parameter caches.\n     *\n     * The meaning of `name` and `version` is specified in\n     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP-712]:\n     *\n     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n     * - `version`: the current major version of the signing domain.\n     *\n     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n     * contract upgrade].\n     */\n    function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n        __EIP712_init_unchained(name, version);\n    }\n\n    function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n        EIP712Storage storage $ = _getEIP712Storage();\n        $._name = name;\n        $._version = version;\n\n        // Reset prior values in storage if upgrading\n        $._hashedName = 0;\n        $._hashedVersion = 0;\n    }\n\n    /**\n     * @dev Returns the domain separator for the current chain.\n     */\n    function _domainSeparatorV4() internal view returns (bytes32) {\n        return _buildDomainSeparator();\n    }\n\n    function _buildDomainSeparator() private view returns (bytes32) {\n        return keccak256(abi.encode(TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n    }\n\n    /**\n     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n     * function returns the hash of the fully encoded EIP712 message for this domain.\n     *\n     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n     *\n     * ```solidity\n     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n     *     keccak256(\"Mail(address to,string contents)\"),\n     *     mailTo,\n     *     keccak256(bytes(mailContents))\n     * )));\n     * address signer = ECDSA.recover(digest, signature);\n     * ```\n     */\n    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n        return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);\n    }\n\n    /// @inheritdoc IERC5267\n    function eip712Domain()\n        public\n        view\n        virtual\n        returns (\n            bytes1 fields,\n            string memory name,\n            string memory version,\n            uint256 chainId,\n            address verifyingContract,\n            bytes32 salt,\n            uint256[] memory extensions\n        )\n    {\n        EIP712Storage storage $ = _getEIP712Storage();\n        // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n        // and the EIP712 domain is not reliable, as it will be missing name and version.\n        require($._hashedName == 0 && $._hashedVersion == 0, \"EIP712: Uninitialized\");\n\n        return (\n            hex\"0f\", // 01111\n            _EIP712Name(),\n            _EIP712Version(),\n            block.chainid,\n            address(this),\n            bytes32(0),\n            new uint256[](0)\n        );\n    }\n\n    /**\n     * @dev The name parameter for the EIP712 domain.\n     *\n     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n     * are a concern.\n     */\n    function _EIP712Name() internal view virtual returns (string memory) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        return $._name;\n    }\n\n    /**\n     * @dev The version parameter for the EIP712 domain.\n     *\n     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n     * are a concern.\n     */\n    function _EIP712Version() internal view virtual returns (string memory) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        return $._version;\n    }\n\n    /**\n     * @dev The hash of the name parameter for the EIP712 domain.\n     *\n     * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n     */\n    function _EIP712NameHash() internal view returns (bytes32) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        string memory name = _EIP712Name();\n        if (bytes(name).length > 0) {\n            return keccak256(bytes(name));\n        } else {\n            // If the name is empty, the contract may have been upgraded without initializing the new storage.\n            // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n            bytes32 hashedName = $._hashedName;\n            if (hashedName != 0) {\n                return hashedName;\n            } else {\n                return keccak256(\"\");\n            }\n        }\n    }\n\n    /**\n     * @dev The hash of the version parameter for the EIP712 domain.\n     *\n     * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n     */\n    function _EIP712VersionHash() internal view returns (bytes32) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        string memory version = _EIP712Version();\n        if (bytes(version).length > 0) {\n            return keccak256(bytes(version));\n        } else {\n            // If the version is empty, the contract may have been upgraded without initializing the new storage.\n            // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n            bytes32 hashedVersion = $._hashedVersion;\n            if (hashedVersion != 0) {\n                return hashedVersion;\n            } else {\n                return keccak256(\"\");\n            }\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.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        if (!_safeTransfer(token, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\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        if (!_safeTransferFrom(token, from, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\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 _safeTransfer(token, to, value, false);\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 _safeTransferFrom(token, from, to, value, false);\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        if (!_safeApprove(token, spender, value, false)) {\n            if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));\n            if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));\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 relies 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 relies 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     * Oppositely, 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 `token.transfer(to, value)` call, relaxing the requirement on the return value: the\n     * return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.transfer.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(to, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return\n     * value: the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param from The sender of the tokens\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value,\n        bool bubble\n    ) private returns (bool success) {\n        bytes4 selector = IERC20.transferFrom.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(from, shr(96, not(0))))\n            mstore(0x24, and(to, shr(96, not(0))))\n            mstore(0x44, value)\n            success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n            mstore(0x60, 0)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:\n     * the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param spender The spender of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.approve.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(spender, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS\n    }\n\n    /**\n     * @dev The signature derives the `address(0)`.\n     */\n    error ECDSAInvalidSignature();\n\n    /**\n     * @dev The signature has an invalid length.\n     */\n    error ECDSAInvalidSignatureLength(uint256 length);\n\n    /**\n     * @dev The signature has an S value that is in the upper half order.\n     */\n    error ECDSAInvalidSignatureS(bytes32 s);\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not\n     * return address(0) without also returning an error description. Errors are documented using an enum (error type)\n     * and a bytes32 providing additional information about the error.\n     *\n     * If no error is returned, then the address can be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * NOTE: This function only supports 65-byte signatures. ERC-2098 short signatures are rejected. This restriction\n     * is DEPRECATED and will be removed in v6.0. Developers SHOULD NOT use signatures as unique identifiers; use hash\n     * invalidation or nonces for replay protection.\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     *\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 Variant of {tryRecover} that takes a signature in calldata\n     */\n    function tryRecoverCalldata(\n        bytes32 hash,\n        bytes calldata 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, calldata slices would work here, but are\n            // significantly more expensive (length check) than using calldataload in assembly.\n            assembly (\"memory-safe\") {\n                r := calldataload(signature.offset)\n                s := calldataload(add(signature.offset, 0x20))\n                v := byte(0, calldataload(add(signature.offset, 0x40)))\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     * NOTE: This function only supports 65-byte signatures. ERC-2098 short signatures are rejected. This restriction\n     * is DEPRECATED and will be removed in v6.0. Developers SHOULD NOT use signatures as unique identifiers; use hash\n     * invalidation or nonces for replay protection.\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 Variant of {recover} that takes a signature in calldata\n     */\n    function recoverCalldata(bytes32 hash, bytes calldata signature) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecoverCalldata(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 Parse a signature into its `v`, `r` and `s` components. Supports 65-byte and 64-byte (ERC-2098)\n     * formats. Returns (0,0,0) for invalid signatures.\n     *\n     * For 64-byte signatures, `v` is automatically normalized to 27 or 28.\n     * For 65-byte signatures, `v` is returned as-is and MUST already be 27 or 28 for use with ecrecover.\n     *\n     * Consider validating the result before use, or use {tryRecover}/{recover} which perform full validation.\n     */\n    function parse(bytes memory signature) internal pure returns (uint8 v, bytes32 r, bytes32 s) {\n        assembly (\"memory-safe\") {\n            // Check the signature length\n            switch mload(signature)\n            // - case 65: r,s,v signature (standard)\n            case 65 {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098)\n            case 64 {\n                let vs := mload(add(signature, 0x40))\n                r := mload(add(signature, 0x20))\n                s := and(vs, shr(1, not(0)))\n                v := add(shr(255, vs), 27)\n            }\n            default {\n                r := 0\n                s := 0\n                v := 0\n            }\n        }\n    }\n\n    /**\n     * @dev Variant of {parse} that takes a signature in calldata\n     */\n    function parseCalldata(bytes calldata signature) internal pure returns (uint8 v, bytes32 r, bytes32 s) {\n        assembly (\"memory-safe\") {\n            // Check the signature length\n            switch signature.length\n            // - case 65: r,s,v signature (standard)\n            case 65 {\n                r := calldataload(signature.offset)\n                s := calldataload(add(signature.offset, 0x20))\n                v := byte(0, calldataload(add(signature.offset, 0x40)))\n            }\n            // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098)\n            case 64 {\n                let vs := calldataload(add(signature.offset, 0x20))\n                r := calldataload(signature.offset)\n                s := and(vs, shr(1, not(0)))\n                v := add(shr(255, vs), 27)\n            }\n            default {\n                r := 0\n                s := 0\n                v := 0\n            }\n        }\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"},{"file_path":"lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (proxy/beacon/IBeacon.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {UpgradeableBeacon} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/Panic.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (proxy/ERC1967/ERC1967Utils.sol)\n\npragma solidity ^0.8.21;\n\nimport {IBeacon} from \"../beacon/IBeacon.sol\";\nimport {IERC1967} from \"../../interfaces/IERC1967.sol\";\nimport {Address} from \"../../utils/Address.sol\";\nimport {StorageSlot} from \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This library provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots.\n */\nlibrary ERC1967Utils {\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev The `implementation` of the proxy is invalid.\n     */\n    error ERC1967InvalidImplementation(address implementation);\n\n    /**\n     * @dev The `admin` of the proxy is invalid.\n     */\n    error ERC1967InvalidAdmin(address admin);\n\n    /**\n     * @dev The `beacon` of the proxy is invalid.\n     */\n    error ERC1967InvalidBeacon(address beacon);\n\n    /**\n     * @dev An upgrade function sees `msg.value > 0` that may be lost.\n     */\n    error ERC1967NonPayable();\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the ERC-1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        if (newImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(newImplementation);\n        }\n        StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Performs implementation upgrade with additional setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-Upgraded} event.\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) internal {\n        _setImplementation(newImplementation);\n        emit IERC1967.Upgraded(newImplementation);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(newImplementation, data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using\n     * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the ERC-1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        if (newAdmin == address(0)) {\n            revert ERC1967InvalidAdmin(address(0));\n        }\n        StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {IERC1967-AdminChanged} event.\n     */\n    function changeAdmin(address newAdmin) internal {\n        emit IERC1967.AdminChanged(getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is the keccak-256 hash of \"eip1967.proxy.beacon\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the ERC-1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        if (newBeacon.code.length == 0) {\n            revert ERC1967InvalidBeacon(newBeacon);\n        }\n\n        StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;\n\n        address beaconImplementation = IBeacon(newBeacon).implementation();\n        if (beaconImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(beaconImplementation);\n        }\n    }\n\n    /**\n     * @dev Change the beacon and trigger a setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-BeaconUpgraded} event.\n     *\n     * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since\n     * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for\n     * efficiency.\n     */\n    function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {\n        _setBeacon(newBeacon);\n        emit IERC1967.BeaconUpgraded(newBeacon);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract\n     * if an upgrade doesn't perform an initialization call.\n     */\n    function _checkNonPayable() private {\n        if (msg.value > 0) {\n            revert ERC1967NonPayable();\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.22;\n\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\";\n"},{"file_path":"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reinitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Pointer to storage slot. Allows integrators to override it with a custom storage location.\n     *\n     * NOTE: Consider following the ERC-7201 formula to derive storage locations.\n     */\n    function _initializableStorageSlot() internal pure virtual returns (bytes32) {\n        return INITIALIZABLE_STORAGE;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        bytes32 slot = _initializableStorageSlot();\n        assembly {\n            $.slot := slot\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},{"file_path":"src/Seizable.sol","source_code":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.34;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @title Seizable\n * @dev Allows court-order-triggered forced transfers (seizure) of tokens (Upgradeable)\n */\nabstract contract Seizable is Initializable {\n    /// @custom:storage-location erc7201:jpysc.storage.Seizable\n    struct SeizableStorage {\n        address _seizer;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"jpysc.storage.Seizable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant SEIZABLE_STORAGE_LOCATION =\n        0xa3fdb05258ab622e74a58362581a283149dca7a127254a327031149afbca3100;\n\n    function _getSeizableStorage() private pure returns (SeizableStorage storage $) {\n        assembly {\n            $.slot := SEIZABLE_STORAGE_LOCATION\n        }\n    }\n\n    event Seized(address indexed from, address indexed to, uint256 amount, bytes32 indexed trackId);\n    event SeizerChanged(address indexed previousSeizer, address indexed newSeizer);\n\n    error NotSeizer(address account);\n    error InvalidSeizer(address seizer);\n    error SeizeFromZeroAddress();\n    error SeizeToZeroAddress();\n    error SeizeFromNotBlacklisted(address from);\n    error SeizeAmountExceedsBalance(address from, uint256 amount, uint256 balance);\n\n    modifier onlySeizer() {\n        if (msg.sender != _getSeizableStorage()._seizer) {\n            revert NotSeizer(msg.sender);\n        }\n        _;\n    }\n\n    function __Seizable_init() internal onlyInitializing {\n        __Seizable_init_unchained();\n    }\n\n    function __Seizable_init_unchained() internal onlyInitializing {}\n\n    function seizer() public view returns (address) {\n        return _getSeizableStorage()._seizer;\n    }\n\n    function _setSeizer(address newSeizer) internal {\n        SeizableStorage storage $ = _getSeizableStorage();\n        address oldSeizer = $._seizer;\n        $._seizer = newSeizer;\n        emit SeizerChanged(oldSeizer, newSeizer);\n    }\n\n    function _initializeSeizer(address initialSeizer) internal {\n        if (initialSeizer == address(0)) {\n            revert InvalidSeizer(address(0));\n        }\n        _getSeizableStorage()._seizer = initialSeizer;\n        emit SeizerChanged(address(0), initialSeizer);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\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"},{"file_path":"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\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"},{"file_path":"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"../IERC20.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"},{"file_path":"lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.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"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.20;\n\nimport {OwnableUpgradeable} from \"./OwnableUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts/proxy/utils/Initializable.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 * This extension of the {Ownable} contract includes a two-step mechanism to transfer\n * ownership, where the new owner must call {acceptOwnership} in order to replace the\n * old one. This can help prevent common mistakes, such as transfers of ownership to\n * incorrect accounts, or to contracts that are unable to interact with the\n * permission system.\n *\n * The initial owner is specified at deployment time in the constructor for `Ownable`. 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    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable2Step\n    struct Ownable2StepStorage {\n        address _pendingOwner;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable2Step\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant Ownable2StepStorageLocation = 0x237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00;\n\n    function _getOwnable2StepStorage() private pure returns (Ownable2StepStorage storage $) {\n        assembly {\n            $.slot := Ownable2StepStorageLocation\n        }\n    }\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    function __Ownable2Step_init() internal onlyInitializing {\n    }\n\n    function __Ownable2Step_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        Ownable2StepStorage storage $ = _getOwnable2StepStorage();\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     * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        Ownable2StepStorage storage $ = _getOwnable2StepStorage();\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        Ownable2StepStorage storage $ = _getOwnable2StepStorage();\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        if (pendingOwner() != sender) {\n            revert OwnableUnauthorizedAccount(sender);\n        }\n        _transferOwnership(sender);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\n    struct OwnableStorage {\n        address _owner;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\n\n    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\n        assembly {\n            $.slot := OwnableStorageLocation\n        }\n    }\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    function __Ownable_init(address initialOwner) internal onlyInitializing {\n        __Ownable_init_unchained(initialOwner);\n    }\n\n    function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        OwnableStorage storage $ = _getOwnableStorage();\n        return $._owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        OwnableStorage storage $ = _getOwnableStorage();\n        address oldOwner = $._owner;\n        $._owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1967.sol)\n\npragma solidity >=0.4.11;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n */\ninterface IERC1967 {\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Emitted when the beacon is changed.\n     */\n    event BeaconUpgraded(address indexed beacon);\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/Strings.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/Strings.sol)\n\npragma solidity ^0.8.24;\n\nimport {Math} from \"./math/Math.sol\";\nimport {SafeCast} from \"./math/SafeCast.sol\";\nimport {SignedMath} from \"./math/SignedMath.sol\";\nimport {Bytes} from \"./Bytes.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    using SafeCast for *;\n\n    bytes16 private constant HEX_DIGITS = \"0123456789abcdef\";\n    uint8 private constant ADDRESS_LENGTH = 20;\n    uint256 private constant SPECIAL_CHARS_LOOKUP =\n        (1 << 0x08) | // backspace\n            (1 << 0x09) | // tab\n            (1 << 0x0a) | // newline\n            (1 << 0x0c) | // form feed\n            (1 << 0x0d) | // carriage return\n            (1 << 0x22) | // double quote\n            (1 << 0x5c); // backslash\n\n    /**\n     * @dev The `value` string doesn't fit in the specified `length`.\n     */\n    error StringsInsufficientHexLength(uint256 value, uint256 length);\n\n    /**\n     * @dev The string being parsed contains characters that are not in scope of the given base.\n     */\n    error StringsInvalidChar();\n\n    /**\n     * @dev The string being parsed is not a properly formatted address.\n     */\n    error StringsInvalidAddressFormat();\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = Math.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            assembly (\"memory-safe\") {\n                ptr := add(add(buffer, 0x20), length)\n            }\n            while (true) {\n                ptr--;\n                assembly (\"memory-safe\") {\n                    mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toStringSigned(int256 value) internal pure returns (string memory) {\n        return string.concat(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value)));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, Math.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        uint256 localValue = value;\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = HEX_DIGITS[localValue & 0xf];\n            localValue >>= 4;\n        }\n        if (localValue != 0) {\n            revert StringsInsufficientHexLength(value, length);\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal\n     * representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal\n     * representation, according to EIP-55.\n     */\n    function toChecksumHexString(address addr) internal pure returns (string memory) {\n        bytes memory buffer = bytes(toHexString(addr));\n\n        // hash the hex part of buffer (skip length + 2 bytes, length 40)\n        uint256 hashValue;\n        assembly (\"memory-safe\") {\n            hashValue := shr(96, keccak256(add(buffer, 0x22), 40))\n        }\n\n        for (uint256 i = 41; i > 1; --i) {\n            // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f)\n            if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) {\n                // case shift by xoring with 0x20\n                buffer[i] ^= 0x20;\n            }\n            hashValue >>= 4;\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts a `bytes` buffer to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(bytes memory input) internal pure returns (string memory) {\n        unchecked {\n            bytes memory buffer = new bytes(2 * input.length + 2);\n            buffer[0] = \"0\";\n            buffer[1] = \"x\";\n            for (uint256 i = 0; i < input.length; ++i) {\n                uint8 v = uint8(input[i]);\n                buffer[2 * i + 2] = HEX_DIGITS[v >> 4];\n                buffer[2 * i + 3] = HEX_DIGITS[v & 0xf];\n            }\n            return string(buffer);\n        }\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return Bytes.equal(bytes(a), bytes(b));\n    }\n\n    /**\n     * @dev Parse a decimal string and returns the value as a `uint256`.\n     *\n     * Requirements:\n     * - The string must be formatted as `[0-9]*`\n     * - The result must fit into an `uint256` type\n     */\n    function parseUint(string memory input) internal pure returns (uint256) {\n        return parseUint(input, 0, bytes(input).length);\n    }\n\n    /**\n     * @dev Variant of {parseUint-string} that parses a substring of `input` located between position `begin` (included) and\n     * `end` (excluded).\n     *\n     * Requirements:\n     * - The substring must be formatted as `[0-9]*`\n     * - The result must fit into an `uint256` type\n     */\n    function parseUint(string memory input, uint256 begin, uint256 end) internal pure returns (uint256) {\n        (bool success, uint256 value) = tryParseUint(input, begin, end);\n        if (!success) revert StringsInvalidChar();\n        return value;\n    }\n\n    /**\n     * @dev Variant of {parseUint-string} that returns false if the parsing fails because of an invalid character.\n     *\n     * NOTE: This function will revert if the result does not fit in a `uint256`.\n     */\n    function tryParseUint(string memory input) internal pure returns (bool success, uint256 value) {\n        return _tryParseUintUncheckedBounds(input, 0, bytes(input).length);\n    }\n\n    /**\n     * @dev Variant of {parseUint-string-uint256-uint256} that returns false if the parsing fails because of an invalid\n     * character.\n     *\n     * NOTE: This function will revert if the result does not fit in a `uint256`.\n     */\n    function tryParseUint(\n        string memory input,\n        uint256 begin,\n        uint256 end\n    ) internal pure returns (bool success, uint256 value) {\n        if (end > bytes(input).length || begin > end) return (false, 0);\n        return _tryParseUintUncheckedBounds(input, begin, end);\n    }\n\n    /**\n     * @dev Implementation of {tryParseUint-string-uint256-uint256} that does not check bounds. Caller should make sure that\n     * `begin <= end <= input.length`. Other inputs would result in undefined behavior.\n     */\n    function _tryParseUintUncheckedBounds(\n        string memory input,\n        uint256 begin,\n        uint256 end\n    ) private pure returns (bool success, uint256 value) {\n        bytes memory buffer = bytes(input);\n\n        uint256 result = 0;\n        for (uint256 i = begin; i < end; ++i) {\n            uint8 chr = _tryParseChr(bytes1(_unsafeReadBytesOffset(buffer, i)));\n            if (chr > 9) return (false, 0);\n            result *= 10;\n            result += chr;\n        }\n        return (true, result);\n    }\n\n    /**\n     * @dev Parse a decimal string and returns the value as a `int256`.\n     *\n     * Requirements:\n     * - The string must be formatted as `[-+]?[0-9]*`\n     * - The result must fit in an `int256` type.\n     */\n    function parseInt(string memory input) internal pure returns (int256) {\n        return parseInt(input, 0, bytes(input).length);\n    }\n\n    /**\n     * @dev Variant of {parseInt-string} that parses a substring of `input` located between position `begin` (included) and\n     * `end` (excluded).\n     *\n     * Requirements:\n     * - The substring must be formatted as `[-+]?[0-9]*`\n     * - The result must fit in an `int256` type.\n     */\n    function parseInt(string memory input, uint256 begin, uint256 end) internal pure returns (int256) {\n        (bool success, int256 value) = tryParseInt(input, begin, end);\n        if (!success) revert StringsInvalidChar();\n        return value;\n    }\n\n    /**\n     * @dev Variant of {parseInt-string} that returns false if the parsing fails because of an invalid character or if\n     * the result does not fit in a `int256`.\n     *\n     * NOTE: This function will revert if the absolute value of the result does not fit in a `uint256`.\n     */\n    function tryParseInt(string memory input) internal pure returns (bool success, int256 value) {\n        return _tryParseIntUncheckedBounds(input, 0, bytes(input).length);\n    }\n\n    uint256 private constant ABS_MIN_INT256 = 2 ** 255;\n\n    /**\n     * @dev Variant of {parseInt-string-uint256-uint256} that returns false if the parsing fails because of an invalid\n     * character or if the result does not fit in a `int256`.\n     *\n     * NOTE: This function will revert if the absolute value of the result does not fit in a `uint256`.\n     */\n    function tryParseInt(\n        string memory input,\n        uint256 begin,\n        uint256 end\n    ) internal pure returns (bool success, int256 value) {\n        if (end > bytes(input).length || begin > end) return (false, 0);\n        return _tryParseIntUncheckedBounds(input, begin, end);\n    }\n\n    /**\n     * @dev Implementation of {tryParseInt-string-uint256-uint256} that does not check bounds. Caller should make sure that\n     * `begin <= end <= input.length`. Other inputs would result in undefined behavior.\n     */\n    function _tryParseIntUncheckedBounds(\n        string memory input,\n        uint256 begin,\n        uint256 end\n    ) private pure returns (bool success, int256 value) {\n        bytes memory buffer = bytes(input);\n\n        // Check presence of a negative sign.\n        bytes1 sign = begin == end ? bytes1(0) : bytes1(_unsafeReadBytesOffset(buffer, begin)); // don't do out-of-bound (possibly unsafe) read if sub-string is empty\n        bool positiveSign = sign == bytes1(\"+\");\n        bool negativeSign = sign == bytes1(\"-\");\n        uint256 offset = (positiveSign || negativeSign).toUint();\n\n        (bool absSuccess, uint256 absValue) = tryParseUint(input, begin + offset, end);\n\n        if (absSuccess && absValue < ABS_MIN_INT256) {\n            return (true, negativeSign ? -int256(absValue) : int256(absValue));\n        } else if (absSuccess && negativeSign && absValue == ABS_MIN_INT256) {\n            return (true, type(int256).min);\n        } else return (false, 0);\n    }\n\n    /**\n     * @dev Parse a hexadecimal string (with or without \"0x\" prefix), and returns the value as a `uint256`.\n     *\n     * Requirements:\n     * - The string must be formatted as `(0x)?[0-9a-fA-F]*`\n     * - The result must fit in an `uint256` type.\n     */\n    function parseHexUint(string memory input) internal pure returns (uint256) {\n        return parseHexUint(input, 0, bytes(input).length);\n    }\n\n    /**\n     * @dev Variant of {parseHexUint-string} that parses a substring of `input` located between position `begin` (included) and\n     * `end` (excluded).\n     *\n     * Requirements:\n     * - The substring must be formatted as `(0x)?[0-9a-fA-F]*`\n     * - The result must fit in an `uint256` type.\n     */\n    function parseHexUint(string memory input, uint256 begin, uint256 end) internal pure returns (uint256) {\n        (bool success, uint256 value) = tryParseHexUint(input, begin, end);\n        if (!success) revert StringsInvalidChar();\n        return value;\n    }\n\n    /**\n     * @dev Variant of {parseHexUint-string} that returns false if the parsing fails because of an invalid character.\n     *\n     * NOTE: This function will revert if the result does not fit in a `uint256`.\n     */\n    function tryParseHexUint(string memory input) internal pure returns (bool success, uint256 value) {\n        return _tryParseHexUintUncheckedBounds(input, 0, bytes(input).length);\n    }\n\n    /**\n     * @dev Variant of {parseHexUint-string-uint256-uint256} that returns false if the parsing fails because of an\n     * invalid character.\n     *\n     * NOTE: This function will revert if the result does not fit in a `uint256`.\n     */\n    function tryParseHexUint(\n        string memory input,\n        uint256 begin,\n        uint256 end\n    ) internal pure returns (bool success, uint256 value) {\n        if (end > bytes(input).length || begin > end) return (false, 0);\n        return _tryParseHexUintUncheckedBounds(input, begin, end);\n    }\n\n    /**\n     * @dev Implementation of {tryParseHexUint-string-uint256-uint256} that does not check bounds. Caller should make sure that\n     * `begin <= end <= input.length`. Other inputs would result in undefined behavior.\n     */\n    function _tryParseHexUintUncheckedBounds(\n        string memory input,\n        uint256 begin,\n        uint256 end\n    ) private pure returns (bool success, uint256 value) {\n        bytes memory buffer = bytes(input);\n\n        // skip 0x prefix if present\n        bool hasPrefix = (end > begin + 1) && bytes2(_unsafeReadBytesOffset(buffer, begin)) == bytes2(\"0x\"); // don't do out-of-bound (possibly unsafe) read if sub-string is empty\n        uint256 offset = hasPrefix.toUint() * 2;\n\n        uint256 result = 0;\n        for (uint256 i = begin + offset; i < end; ++i) {\n            uint8 chr = _tryParseChr(bytes1(_unsafeReadBytesOffset(buffer, i)));\n            if (chr > 15) return (false, 0);\n            result *= 16;\n            unchecked {\n                // Multiplying by 16 is equivalent to a shift of 4 bits (with additional overflow check).\n                // This guarantees that adding a value < 16 will not cause an overflow, hence the unchecked.\n                result += chr;\n            }\n        }\n        return (true, result);\n    }\n\n    /**\n     * @dev Parse a hexadecimal string (with or without \"0x\" prefix), and returns the value as an `address`.\n     *\n     * Requirements:\n     * - The string must be formatted as `(0x)?[0-9a-fA-F]{40}`\n     */\n    function parseAddress(string memory input) internal pure returns (address) {\n        return parseAddress(input, 0, bytes(input).length);\n    }\n\n    /**\n     * @dev Variant of {parseAddress-string} that parses a substring of `input` located between position `begin` (included) and\n     * `end` (excluded).\n     *\n     * Requirements:\n     * - The substring must be formatted as `(0x)?[0-9a-fA-F]{40}`\n     */\n    function parseAddress(string memory input, uint256 begin, uint256 end) internal pure returns (address) {\n        (bool success, address value) = tryParseAddress(input, begin, end);\n        if (!success) revert StringsInvalidAddressFormat();\n        return value;\n    }\n\n    /**\n     * @dev Variant of {parseAddress-string} that returns false if the parsing fails because the input is not a properly\n     * formatted address. See {parseAddress-string} requirements.\n     */\n    function tryParseAddress(string memory input) internal pure returns (bool success, address value) {\n        return tryParseAddress(input, 0, bytes(input).length);\n    }\n\n    /**\n     * @dev Variant of {parseAddress-string-uint256-uint256} that returns false if the parsing fails because input is not a properly\n     * formatted address. See {parseAddress-string-uint256-uint256} requirements.\n     */\n    function tryParseAddress(\n        string memory input,\n        uint256 begin,\n        uint256 end\n    ) internal pure returns (bool success, address value) {\n        if (end > bytes(input).length || begin > end) return (false, address(0));\n\n        bool hasPrefix = (end > begin + 1) && bytes2(_unsafeReadBytesOffset(bytes(input), begin)) == bytes2(\"0x\"); // don't do out-of-bound (possibly unsafe) read if sub-string is empty\n        uint256 expectedLength = 40 + hasPrefix.toUint() * 2;\n\n        // check that input is the correct length\n        if (end - begin == expectedLength) {\n            // length guarantees that this does not overflow, and value is at most type(uint160).max\n            (bool s, uint256 v) = _tryParseHexUintUncheckedBounds(input, begin, end);\n            return (s, address(uint160(v)));\n        } else {\n            return (false, address(0));\n        }\n    }\n\n    function _tryParseChr(bytes1 chr) private pure returns (uint8) {\n        uint8 value = uint8(chr);\n\n        // Try to parse `chr`:\n        // - Case 1: [0-9]\n        // - Case 2: [a-f]\n        // - Case 3: [A-F]\n        // - otherwise not supported\n        unchecked {\n            if (value > 47 && value < 58) value -= 48;\n            else if (value > 96 && value < 103) value -= 87;\n            else if (value > 64 && value < 71) value -= 55;\n            else return type(uint8).max;\n        }\n\n        return value;\n    }\n\n    /**\n     * @dev Escape special characters in JSON strings. This can be useful to prevent JSON injection in NFT metadata.\n     *\n     * WARNING: This function should only be used in double quoted JSON strings. Single quotes are not escaped.\n     *\n     * NOTE: This function escapes all unicode characters, and not just the ones in ranges defined in section 2.5 of\n     * RFC-4627 (U+0000 to U+001F, U+0022 and U+005C). ECMAScript's `JSON.parse` does recover escaped unicode\n     * characters that are not in this range, but other tooling may provide different results.\n     */\n    function escapeJSON(string memory input) internal pure returns (string memory) {\n        bytes memory buffer = bytes(input);\n        bytes memory output = new bytes(2 * buffer.length); // worst case scenario\n        uint256 outputLength = 0;\n\n        for (uint256 i = 0; i < buffer.length; ++i) {\n            bytes1 char = bytes1(_unsafeReadBytesOffset(buffer, i));\n            if (((SPECIAL_CHARS_LOOKUP & (1 << uint8(char))) != 0)) {\n                output[outputLength++] = \"\\\\\";\n                if (char == 0x08) output[outputLength++] = \"b\";\n                else if (char == 0x09) output[outputLength++] = \"t\";\n                else if (char == 0x0a) output[outputLength++] = \"n\";\n                else if (char == 0x0c) output[outputLength++] = \"f\";\n                else if (char == 0x0d) output[outputLength++] = \"r\";\n                else if (char == 0x5c) output[outputLength++] = \"\\\\\";\n                else if (char == 0x22) {\n                    // solhint-disable-next-line quotes\n                    output[outputLength++] = '\"';\n                }\n            } else {\n                output[outputLength++] = char;\n            }\n        }\n        // write the actual length and deallocate unused memory\n        assembly (\"memory-safe\") {\n            mstore(output, outputLength)\n            mstore(0x40, add(output, shl(5, shr(5, add(outputLength, 63)))))\n        }\n\n        return string(output);\n    }\n\n    /**\n     * @dev Reads a bytes32 from a bytes array without bounds checking.\n     *\n     * NOTE: making this function internal would mean it could be used with memory unsafe offset, and marking the\n     * assembly block as such would prevent some optimizations.\n     */\n    function _unsafeReadBytesOffset(bytes memory buffer, uint256 offset) private pure returns (bytes32 value) {\n        // This is not memory safe in the general case, but all calls to this private function are within bounds.\n        assembly (\"memory-safe\") {\n            value := mload(add(add(buffer, 0x20), offset))\n        }\n    }\n}\n"},{"file_path":"src/Blacklistable.sol","source_code":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.34;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @title Blacklistable\n * @dev Allows blocking addresses from token operations (Upgradeable)\n */\nabstract contract Blacklistable is Initializable {\n    /// @custom:storage-location erc7201:jpysc.storage.Blacklistable\n    struct BlacklistableStorage {\n        address _blacklister;\n        mapping(address => bool) _blacklisted;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"jpysc.storage.Blacklistable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant BLACKLISTABLE_STORAGE_LOCATION =\n        0x47ed0176f22c22a784fdb48f2353dc4c94f71ba0c26201793c80bae6a2d59c00;\n\n    function _getBlacklistableStorage() private pure returns (BlacklistableStorage storage $) {\n        assembly {\n            $.slot := BLACKLISTABLE_STORAGE_LOCATION\n        }\n    }\n\n    event Blacklisted(address indexed account);\n    event UnBlacklisted(address indexed account);\n    event BlacklisterChanged(address indexed previousBlacklister, address indexed newBlacklister);\n\n    error AccountBlacklisted(address account);\n    error AccountAlreadyBlacklisted(address account);\n    error AccountNotBlacklisted(address account);\n    error NotBlacklister(address account);\n    error InvalidBlacklister(address blacklister);\n\n    modifier notBlacklisted(address account) {\n        _requireNotBlacklisted(account);\n        _;\n    }\n\n    modifier onlyBlacklister() {\n        if (msg.sender != _getBlacklistableStorage()._blacklister) {\n            revert NotBlacklister(msg.sender);\n        }\n        _;\n    }\n\n    function __Blacklistable_init() internal onlyInitializing {\n        __Blacklistable_init_unchained();\n    }\n\n    function __Blacklistable_init_unchained() internal onlyInitializing {}\n\n    function blacklister() public view returns (address) {\n        return _getBlacklistableStorage()._blacklister;\n    }\n\n    function isBlacklisted(address account) public view returns (bool) {\n        return _getBlacklistableStorage()._blacklisted[account];\n    }\n\n    function _requireNotBlacklisted(address account) internal view {\n        if (_getBlacklistableStorage()._blacklisted[account]) {\n            revert AccountBlacklisted(account);\n        }\n    }\n\n    function blacklist(address account) external onlyBlacklister {\n        if (_getBlacklistableStorage()._blacklisted[account]) revert AccountAlreadyBlacklisted(account);\n        _getBlacklistableStorage()._blacklisted[account] = true;\n        emit Blacklisted(account);\n    }\n\n    function unBlacklist(address account) external onlyBlacklister {\n        if (!_getBlacklistableStorage()._blacklisted[account]) revert AccountNotBlacklisted(account);\n        _getBlacklistableStorage()._blacklisted[account] = false;\n        emit UnBlacklisted(account);\n    }\n\n    function blacklistBulk(address[] calldata accounts) external onlyBlacklister {\n        BlacklistableStorage storage $ = _getBlacklistableStorage();\n        for (uint256 i = 0; i < accounts.length; i++) {\n            if ($._blacklisted[accounts[i]]) revert AccountAlreadyBlacklisted(accounts[i]);\n            $._blacklisted[accounts[i]] = true;\n            emit Blacklisted(accounts[i]);\n        }\n    }\n\n    function unBlacklistBulk(address[] calldata accounts) external onlyBlacklister {\n        BlacklistableStorage storage $ = _getBlacklistableStorage();\n        for (uint256 i = 0; i < accounts.length; i++) {\n            if (!$._blacklisted[accounts[i]]) revert AccountNotBlacklisted(accounts[i]);\n            $._blacklisted[accounts[i]] = false;\n            emit UnBlacklisted(accounts[i]);\n        }\n    }\n\n    function _setBlacklister(address newBlacklister) internal {\n        BlacklistableStorage storage $ = _getBlacklistableStorage();\n        address oldBlacklister = $._blacklister;\n        $._blacklister = newBlacklister;\n        emit BlacklisterChanged(oldBlacklister, newBlacklister);\n    }\n\n    function _initializeBlacklister(address initialBlacklister) internal {\n        if (initialBlacklister == address(0)) {\n            revert InvalidBlacklister(address(0));\n        }\n        _getBlacklistableStorage()._blacklister = initialBlacklister;\n        emit BlacklisterChanged(address(0), initialBlacklister);\n    }\n}\n"},{"file_path":"src/AssetRecovery.sol","source_code":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.34;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @title AssetRecovery\n * @dev Allows recovery of ERC-20 tokens accidentally sent to this contract (Upgradeable)\n */\nabstract contract AssetRecovery is Initializable {\n    using SafeERC20 for IERC20;\n\n    /// @custom:storage-location erc7201:jpysc.storage.AssetRecovery\n    struct AssetRecoveryStorage {\n        address _assetRecoverer;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"jpysc.storage.AssetRecovery\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant ASSET_RECOVERY_STORAGE_LOCATION =\n        0x54277b0927ea5af1a08341ee9f905cc2cd003dcc021c2710bcea482634e0df00;\n\n    function _getAssetRecoveryStorage() private pure returns (AssetRecoveryStorage storage $) {\n        assembly {\n            $.slot := ASSET_RECOVERY_STORAGE_LOCATION\n        }\n    }\n\n    event AssetRecovererChanged(address indexed previousRecoverer, address indexed newRecoverer);\n    event AssetRecovered(address indexed tokenContract, address indexed from, address indexed to, uint256 amount);\n\n    error NotAssetRecoverer(address account);\n    error InvalidAssetRecoverer(address recoverer);\n\n    modifier onlyAssetRecoverer() {\n        if (msg.sender != _getAssetRecoveryStorage()._assetRecoverer) {\n            revert NotAssetRecoverer(msg.sender);\n        }\n        _;\n    }\n\n    function __AssetRecovery_init() internal onlyInitializing {\n        __AssetRecovery_init_unchained();\n    }\n\n    function __AssetRecovery_init_unchained() internal onlyInitializing {}\n\n    function assetRecoverer() public view returns (address) {\n        return _getAssetRecoveryStorage()._assetRecoverer;\n    }\n\n    function recoverERC20(address tokenContract, address to, uint256 amount) external onlyAssetRecoverer {\n        IERC20(tokenContract).safeTransfer(to, amount);\n        emit AssetRecovered(tokenContract, address(this), to, amount);\n    }\n\n    function _setAssetRecoverer(address newRecoverer) internal {\n        AssetRecoveryStorage storage $ = _getAssetRecoveryStorage();\n        address oldRecoverer = $._assetRecoverer;\n        $._assetRecoverer = newRecoverer;\n        emit AssetRecovererChanged(oldRecoverer, newRecoverer);\n    }\n\n    function _initializeAssetRecoverer(address initialRecoverer) internal {\n        if (initialRecoverer == address(0)) {\n            revert InvalidAssetRecoverer(address(0));\n        }\n        _getAssetRecoveryStorage()._assetRecoverer = initialRecoverer;\n        emit AssetRecovererChanged(address(0), initialRecoverer);\n    }\n}\n"},{"file_path":"src/EIP2612.sol","source_code":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.34;\n\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @title EIP2612\n * @dev EIP-2612 permit functionality for gasless approvals (Upgradeable)\n */\nabstract contract EIP2612 is Initializable, EIP712Upgradeable {\n    /// @custom:storage-location erc7201:jpysc.storage.EIP2612\n    struct EIP2612Storage {\n        mapping(address => uint256) _nonces;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"jpysc.storage.EIP2612\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant EIP2612_STORAGE_LOCATION =\n        0xf2d07356d6de72b0c6efa1bb9141b750918118984fbc77dd4a5772f4f973b600;\n\n    function _getEIP2612Storage() private pure returns (EIP2612Storage storage $) {\n        assembly {\n            $.slot := EIP2612_STORAGE_LOCATION\n        }\n    }\n\n    bytes32 private constant PERMIT_TYPEHASH =\n        keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n    error PermitExpired(uint256 deadline);\n    error InvalidSignature();\n\n    function __EIP2612_init(string memory name, string memory version) internal onlyInitializing {\n        __EIP712_init(name, version);\n        __EIP2612_init_unchained();\n    }\n\n    function __EIP2612_init_unchained() internal onlyInitializing {}\n\n    function nonces(address owner) public view returns (uint256) {\n        return _getEIP2612Storage()._nonces[owner];\n    }\n\n    function DOMAIN_SEPARATOR() external view returns (bytes32) {\n        return _domainSeparatorV4();\n    }\n\n    function _permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)\n        internal\n    {\n        if (block.timestamp > deadline) {\n            revert PermitExpired(deadline);\n        }\n\n        EIP2612Storage storage $ = _getEIP2612Storage();\n        uint256 currentNonce = $._nonces[owner];\n\n        bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentNonce, deadline));\n\n        bytes32 hash = _hashTypedDataV4(structHash);\n        address signer = ECDSA.recover(hash, v, r, s);\n\n        if (signer != owner) {\n            revert InvalidSignature();\n        }\n\n        // Commit nonce only after successful verification (defensive programming).\n        // Aligns with ERC3009 in this codebase and OpenZeppelin's modern _useNonce() pattern.\n        unchecked {\n            $._nonces[owner] = currentNonce + 1;\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.20;\n\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * int256(SafeCast.toUint(condition)));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // Formula from the \"Bit Twiddling Hacks\" by Sean Eron Anderson.\n            // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift,\n            // taking advantage of the most significant (or \"sign\" bit) in two's complement representation.\n            // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result,\n            // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative).\n            int256 mask = n >> 255;\n\n            // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it.\n            return uint256((n + mask) ^ mask);\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/interfaces/IERC5267.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC5267.sol)\n\npragma solidity >=0.4.16;\n\ninterface IERC5267 {\n    /**\n     * @dev MAY be emitted to signal that the domain could have changed.\n     */\n    event EIP712DomainChanged();\n\n    /**\n     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n     * signature.\n     */\n    function eip712Domain()\n        external\n        view\n        returns (\n            bytes1 fields,\n            string memory name,\n            string memory version,\n            uint256 chainId,\n            address verifyingContract,\n            bytes32 salt,\n            uint256[] memory extensions\n        );\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev An uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n\n    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/Errors.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of common custom errors used in multiple contracts\n *\n * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.\n * It is recommended to avoid relying on the error API for critical functionality.\n *\n * _Available since v5.1._\n */\nlibrary Errors {\n    /**\n     * @dev The ETH balance of the account is not enough to perform the operation.\n     */\n    error InsufficientBalance(uint256 balance, uint256 needed);\n\n    /**\n     * @dev A call to an address target failed. The target may have reverted.\n     */\n    error FailedCall();\n\n    /**\n     * @dev The deployment failed.\n     */\n    error FailedDeployment();\n\n    /**\n     * @dev A necessary precompile is missing.\n     */\n    error MissingPrecompile(address);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/utils/PausableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts/proxy/utils/Initializable.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    /// @custom:storage-location erc7201:openzeppelin.storage.Pausable\n    struct PausableStorage {\n        bool _paused;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Pausable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300;\n\n    function _getPausableStorage() private pure returns (PausableStorage storage $) {\n        assembly {\n            $.slot := PausableStorageLocation\n        }\n    }\n\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    /**\n     * @dev The operation failed because the contract is paused.\n     */\n    error EnforcedPause();\n\n    /**\n     * @dev The operation failed because the contract is not paused.\n     */\n    error ExpectedPause();\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    function __Pausable_init() internal onlyInitializing {\n    }\n\n    function __Pausable_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        PausableStorage storage $ = _getPausableStorage();\n        return $._paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        if (paused()) {\n            revert EnforcedPause();\n        }\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        if (!paused()) {\n            revert ExpectedPause();\n        }\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        PausableStorage storage $ = _getPausableStorage();\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        PausableStorage storage $ = _getPausableStorage();\n        $._paused = false;\n        emit Unpaused(_msgSender());\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/Bytes.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/Bytes.sol)\n\npragma solidity ^0.8.24;\n\nimport {Math} from \"./math/Math.sol\";\n\n/**\n * @dev Bytes operations.\n */\nlibrary Bytes {\n    /**\n     * @dev Forward search for `s` in `buffer`\n     * * If `s` is present in the buffer, returns the index of the first instance\n     * * If `s` is not present in the buffer, returns type(uint256).max\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf[Javascript's `Array.indexOf`]\n     */\n    function indexOf(bytes memory buffer, bytes1 s) internal pure returns (uint256) {\n        return indexOf(buffer, s, 0);\n    }\n\n    /**\n     * @dev Forward search for `s` in `buffer` starting at position `pos`\n     * * If `s` is present in the buffer (at or after `pos`), returns the index of the next instance\n     * * If `s` is not present in the buffer (at or after `pos`), returns type(uint256).max\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf[Javascript's `Array.indexOf`]\n     */\n    function indexOf(bytes memory buffer, bytes1 s, uint256 pos) internal pure returns (uint256) {\n        uint256 length = buffer.length;\n        for (uint256 i = pos; i < length; ++i) {\n            if (bytes1(_unsafeReadBytesOffset(buffer, i)) == s) {\n                return i;\n            }\n        }\n        return type(uint256).max;\n    }\n\n    /**\n     * @dev Backward search for `s` in `buffer`\n     * * If `s` is present in the buffer, returns the index of the last instance\n     * * If `s` is not present in the buffer, returns type(uint256).max\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf[Javascript's `Array.lastIndexOf`]\n     */\n    function lastIndexOf(bytes memory buffer, bytes1 s) internal pure returns (uint256) {\n        return lastIndexOf(buffer, s, type(uint256).max);\n    }\n\n    /**\n     * @dev Backward search for `s` in `buffer` starting at position `pos`\n     * * If `s` is present in the buffer (at or before `pos`), returns the index of the previous instance\n     * * If `s` is not present in the buffer (at or before `pos`), returns type(uint256).max\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf[Javascript's `Array.lastIndexOf`]\n     */\n    function lastIndexOf(bytes memory buffer, bytes1 s, uint256 pos) internal pure returns (uint256) {\n        unchecked {\n            uint256 length = buffer.length;\n            for (uint256 i = Math.min(Math.saturatingAdd(pos, 1), length); i > 0; --i) {\n                if (bytes1(_unsafeReadBytesOffset(buffer, i - 1)) == s) {\n                    return i - 1;\n                }\n            }\n            return type(uint256).max;\n        }\n    }\n\n    /**\n     * @dev Copies the content of `buffer`, from `start` (included) to the end of `buffer` into a new bytes object in\n     * memory.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(bytes memory buffer, uint256 start) internal pure returns (bytes memory) {\n        return slice(buffer, start, buffer.length);\n    }\n\n    /**\n     * @dev Copies the content of `buffer`, from `start` (included) to `end` (excluded) into a new bytes object in\n     * memory. The `end` argument is truncated to the length of the `buffer`.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(bytes memory buffer, uint256 start, uint256 end) internal pure returns (bytes memory) {\n        // sanitize\n        end = Math.min(end, buffer.length);\n        start = Math.min(start, end);\n\n        // allocate and copy\n        bytes memory result = new bytes(end - start);\n        assembly (\"memory-safe\") {\n            mcopy(add(result, 0x20), add(add(buffer, 0x20), start), sub(end, start))\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Moves the content of `buffer`, from `start` (included) to the end of `buffer` to the start of that buffer.\n     *\n     * NOTE: This function modifies the provided buffer in place. If you need to preserve the original buffer, use {slice} instead\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice[Javascript's `Array.splice`]\n     */\n    function splice(bytes memory buffer, uint256 start) internal pure returns (bytes memory) {\n        return splice(buffer, start, buffer.length);\n    }\n\n    /**\n     * @dev Moves the content of `buffer`, from `start` (included) to end (excluded) to the start of that buffer. The\n     * `end` argument is truncated to the length of the `buffer`.\n     *\n     * NOTE: This function modifies the provided buffer in place. If you need to preserve the original buffer, use {slice} instead\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice[Javascript's `Array.splice`]\n     */\n    function splice(bytes memory buffer, uint256 start, uint256 end) internal pure returns (bytes memory) {\n        // sanitize\n        end = Math.min(end, buffer.length);\n        start = Math.min(start, end);\n\n        // allocate and copy\n        assembly (\"memory-safe\") {\n            mcopy(add(buffer, 0x20), add(add(buffer, 0x20), start), sub(end, start))\n            mstore(buffer, sub(end, start))\n        }\n\n        return buffer;\n    }\n\n    /**\n     * @dev Concatenate an array of bytes into a single bytes object.\n     *\n     * For fixed bytes types, we recommend using the solidity built-in `bytes.concat` or (equivalent)\n     * `abi.encodePacked`.\n     *\n     * NOTE: this could be done in assembly with a single loop that expands starting at the FMP, but that would be\n     * significantly less readable. It might be worth benchmarking the savings of the full-assembly approach.\n     */\n    function concat(bytes[] memory buffers) internal pure returns (bytes memory) {\n        uint256 length = 0;\n        for (uint256 i = 0; i < buffers.length; ++i) {\n            length += buffers[i].length;\n        }\n\n        bytes memory result = new bytes(length);\n\n        uint256 offset = 0x20;\n        for (uint256 i = 0; i < buffers.length; ++i) {\n            bytes memory input = buffers[i];\n            assembly (\"memory-safe\") {\n                mcopy(add(result, offset), add(input, 0x20), mload(input))\n            }\n            unchecked {\n                offset += input.length;\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Returns true if the two byte buffers are equal.\n     */\n    function equal(bytes memory a, bytes memory b) internal pure returns (bool) {\n        return a.length == b.length && keccak256(a) == keccak256(b);\n    }\n\n    /**\n     * @dev Reverses the byte order of a bytes32 value, converting between little-endian and big-endian.\n     * Inspired by https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel[Reverse Parallel]\n     */\n    function reverseBytes32(bytes32 value) internal pure returns (bytes32) {\n        value = // swap bytes\n            ((value >> 8) & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n            ((value & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);\n        value = // swap 2-byte long pairs\n            ((value >> 16) & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n            ((value & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);\n        value = // swap 4-byte long pairs\n            ((value >> 32) & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n            ((value & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);\n        value = // swap 8-byte long pairs\n            ((value >> 64) & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n            ((value & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);\n        return (value >> 128) | (value << 128); // swap 16-byte long pairs\n    }\n\n    /// @dev Same as {reverseBytes32} but optimized for 128-bit values.\n    function reverseBytes16(bytes16 value) internal pure returns (bytes16) {\n        value = // swap bytes\n            ((value & 0xFF00FF00FF00FF00FF00FF00FF00FF00) >> 8) |\n            ((value & 0x00FF00FF00FF00FF00FF00FF00FF00FF) << 8);\n        value = // swap 2-byte long pairs\n            ((value & 0xFFFF0000FFFF0000FFFF0000FFFF0000) >> 16) |\n            ((value & 0x0000FFFF0000FFFF0000FFFF0000FFFF) << 16);\n        value = // swap 4-byte long pairs\n            ((value & 0xFFFFFFFF00000000FFFFFFFF00000000) >> 32) |\n            ((value & 0x00000000FFFFFFFF00000000FFFFFFFF) << 32);\n        return (value >> 64) | (value << 64); // swap 8-byte long pairs\n    }\n\n    /// @dev Same as {reverseBytes32} but optimized for 64-bit values.\n    function reverseBytes8(bytes8 value) internal pure returns (bytes8) {\n        value = ((value & 0xFF00FF00FF00FF00) >> 8) | ((value & 0x00FF00FF00FF00FF) << 8); // swap bytes\n        value = ((value & 0xFFFF0000FFFF0000) >> 16) | ((value & 0x0000FFFF0000FFFF) << 16); // swap 2-byte long pairs\n        return (value >> 32) | (value << 32); // swap 4-byte long pairs\n    }\n\n    /// @dev Same as {reverseBytes32} but optimized for 32-bit values.\n    function reverseBytes4(bytes4 value) internal pure returns (bytes4) {\n        value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); // swap bytes\n        return (value >> 16) | (value << 16); // swap 2-byte long pairs\n    }\n\n    /// @dev Same as {reverseBytes32} but optimized for 16-bit values.\n    function reverseBytes2(bytes2 value) internal pure returns (bytes2) {\n        return (value >> 8) | (value << 8);\n    }\n\n    /**\n     * @dev Counts the number of leading zero bits a bytes array. Returns `8 * buffer.length`\n     * if the buffer is all zeros.\n     */\n    function clz(bytes memory buffer) internal pure returns (uint256) {\n        for (uint256 i = 0; i < buffer.length; i += 0x20) {\n            bytes32 chunk = _unsafeReadBytesOffset(buffer, i);\n            if (chunk != bytes32(0)) {\n                return Math.min(8 * i + Math.clz(uint256(chunk)), 8 * buffer.length);\n            }\n        }\n        return 8 * buffer.length;\n    }\n\n    /**\n     * @dev Reads a bytes32 from a bytes array without bounds checking.\n     *\n     * NOTE: making this function internal would mean it could be used with memory unsafe offset, and marking the\n     * assembly block as such would prevent some optimizations.\n     */\n    function _unsafeReadBytesOffset(bytes memory buffer, uint256 offset) private pure returns (bytes32 value) {\n        // This is not memory safe in the general case, but all calls to this private function are within bounds.\n        assembly (\"memory-safe\") {\n            value := mload(add(add(buffer, 0x20), offset))\n        }\n    }\n}\n"},{"file_path":"src/Whitelistable.sol","source_code":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.34;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @title Whitelistable\n * @dev Allows a whitelist manager to configure whitelisted destination addresses for minting (Upgradeable)\n */\nabstract contract Whitelistable is Initializable {\n    /// @custom:storage-location erc7201:jpysc.storage.Whitelistable\n    struct WhitelistableStorage {\n        address _whitelistManager;\n        // minter => (to address => whitelisted)\n        mapping(address => mapping(address => bool)) _mintWhitelist;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"jpysc.storage.Whitelistable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant WHITELISTABLE_STORAGE_LOCATION =\n        0x907aa7cd286c6c1c6e0026cabd242a3a452cc166cb408ce6cfd4ee25c4cff700;\n\n    function _getWhitelistableStorage() private pure returns (WhitelistableStorage storage $) {\n        assembly {\n            $.slot := WHITELISTABLE_STORAGE_LOCATION\n        }\n    }\n\n    event MintDestinationWhitelisted(address indexed minter, address indexed account);\n    event MintDestinationUnwhitelisted(address indexed minter, address indexed account);\n    event WhitelistManagerChanged(address indexed previousWhitelistManager, address indexed newWhitelistManager);\n\n    error MintDestinationNotWhitelisted(address minter, address to);\n    error InvalidMintDestination(address account);\n    error MintDestinationAlreadyWhitelisted(address minter, address account);\n    error NotWhitelistManager(address account);\n    error InvalidWhitelistManager(address whitelistManager);\n\n    modifier onlyWhitelistManager() {\n        if (msg.sender != _getWhitelistableStorage()._whitelistManager) {\n            revert NotWhitelistManager(msg.sender);\n        }\n        _;\n    }\n\n    modifier onlyWhitelisted(address to) {\n        if (!_getWhitelistableStorage()._mintWhitelist[msg.sender][to]) {\n            revert MintDestinationNotWhitelisted(msg.sender, to);\n        }\n        _;\n    }\n\n    function __Whitelistable_init() internal onlyInitializing {\n        __Whitelistable_init_unchained();\n    }\n\n    function __Whitelistable_init_unchained() internal onlyInitializing {}\n\n    function whitelistManager() public view returns (address) {\n        return _getWhitelistableStorage()._whitelistManager;\n    }\n\n    function isMintWhitelisted(address minter, address to) public view returns (bool) {\n        return _getWhitelistableStorage()._mintWhitelist[minter][to];\n    }\n\n    function _whitelistMintDestination(address minter, address account) internal {\n        if (account == address(0)) revert InvalidMintDestination(address(0));\n        if (_getWhitelistableStorage()._mintWhitelist[minter][account]) {\n            revert MintDestinationAlreadyWhitelisted(minter, account);\n        }\n        _getWhitelistableStorage()._mintWhitelist[minter][account] = true;\n        emit MintDestinationWhitelisted(minter, account);\n    }\n\n    function _unwhitelistMintDestination(address minter, address account) internal {\n        if (!_getWhitelistableStorage()._mintWhitelist[minter][account]) {\n            revert MintDestinationNotWhitelisted(minter, account);\n        }\n        _getWhitelistableStorage()._mintWhitelist[minter][account] = false;\n        emit MintDestinationUnwhitelisted(minter, account);\n    }\n\n    function _setWhitelistManager(address newWhitelistManager) internal {\n        WhitelistableStorage storage $ = _getWhitelistableStorage();\n        address oldWhitelistManager = $._whitelistManager;\n        $._whitelistManager = newWhitelistManager;\n        emit WhitelistManagerChanged(oldWhitelistManager, newWhitelistManager);\n    }\n\n    function _initializeWhitelistManager(address initialWhitelistManager) internal {\n        if (initialWhitelistManager == address(0)) {\n            revert InvalidWhitelistManager(address(0));\n        }\n        _getWhitelistableStorage()._whitelistManager = initialWhitelistManager;\n        emit WhitelistManagerChanged(address(0), initialWhitelistManager);\n    }\n}\n"},{"file_path":"src/ERC3009.sol","source_code":"// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.34;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC3009Upgradeable\n * @dev ERC-3009 transferWithAuthorization functionality for gasless transfers (Upgradeable)\n * Requires the implementing contract to provide _hashTypedDataV4\n */\nabstract contract ERC3009Upgradeable is Initializable {\n    /// @custom:storage-location erc7201:jpysc.storage.ERC3009\n    struct EIP3009Storage {\n        mapping(address => mapping(bytes32 => bool)) _authorizationStates;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"jpysc.storage.ERC3009\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant EIP3009_STORAGE_LOCATION =\n        0x0cc3a6a7ed0ec31d88893e315a1f53bbfc40f20e80bd43bcdac1eb4625e99200;\n\n    function _getEIP3009Storage() private pure returns (EIP3009Storage storage $) {\n        assembly {\n            $.slot := EIP3009_STORAGE_LOCATION\n        }\n    }\n\n    bytes32 private constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH = keccak256(\n        \"TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)\"\n    );\n\n    bytes32 private constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH = keccak256(\n        \"ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)\"\n    );\n\n    bytes32 private constant CANCEL_AUTHORIZATION_TYPEHASH =\n        keccak256(\"CancelAuthorization(address authorizer,bytes32 nonce)\");\n\n    event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);\n    event AuthorizationCanceled(address indexed authorizer, bytes32 indexed nonce);\n\n    error AuthorizationNotYetValid(uint256 validAfter);\n    error AuthorizationExpired(uint256 validBefore);\n    error AuthorizationAlreadyUsed(address authorizer, bytes32 nonce);\n    error CallerMustBePayee(address caller, address payee);\n    error InvalidAuthorizationSignature();\n\n    function __EIP3009_init() internal onlyInitializing {\n        __EIP3009_init_unchained();\n    }\n\n    function __EIP3009_init_unchained() internal onlyInitializing {}\n\n    function authorizationState(address authorizer, bytes32 nonce) public view returns (bool) {\n        return _getEIP3009Storage()._authorizationStates[authorizer][nonce];\n    }\n\n    function _hashTypedDataV4ForAuth(bytes32 structHash) internal view virtual returns (bytes32);\n\n    function _transferWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal returns (address) {\n        _validateAuthorization(from, nonce, validAfter, validBefore);\n\n        bytes32 structHash = keccak256(\n            abi.encode(TRANSFER_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce)\n        );\n\n        bytes32 hash = _hashTypedDataV4ForAuth(structHash);\n        address signer = ECDSA.recover(hash, v, r, s);\n\n        if (signer != from) {\n            revert InvalidAuthorizationSignature();\n        }\n\n        _markAuthorizationUsed(from, nonce);\n        return from;\n    }\n\n    function _receiveWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal returns (address) {\n        if (to != msg.sender) {\n            revert CallerMustBePayee(msg.sender, to);\n        }\n\n        _validateAuthorization(from, nonce, validAfter, validBefore);\n\n        bytes32 structHash =\n            keccak256(abi.encode(RECEIVE_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce));\n\n        bytes32 hash = _hashTypedDataV4ForAuth(structHash);\n        address signer = ECDSA.recover(hash, v, r, s);\n\n        if (signer != from) {\n            revert InvalidAuthorizationSignature();\n        }\n\n        _markAuthorizationUsed(from, nonce);\n        return from;\n    }\n\n    function _cancelAuthorization(address authorizer, bytes32 nonce, uint8 v, bytes32 r, bytes32 s) internal {\n        EIP3009Storage storage $ = _getEIP3009Storage();\n        if ($._authorizationStates[authorizer][nonce]) {\n            revert AuthorizationAlreadyUsed(authorizer, nonce);\n        }\n\n        bytes32 structHash = keccak256(abi.encode(CANCEL_AUTHORIZATION_TYPEHASH, authorizer, nonce));\n\n        bytes32 hash = _hashTypedDataV4ForAuth(structHash);\n        address signer = ECDSA.recover(hash, v, r, s);\n\n        if (signer != authorizer) {\n            revert InvalidAuthorizationSignature();\n        }\n\n        $._authorizationStates[authorizer][nonce] = true;\n        emit AuthorizationCanceled(authorizer, nonce);\n    }\n\n    function _validateAuthorization(address authorizer, bytes32 nonce, uint256 validAfter, uint256 validBefore)\n        private\n        view\n    {\n        if (block.timestamp <= validAfter) {\n            revert AuthorizationNotYetValid(validAfter);\n        }\n        if (block.timestamp >= validBefore) {\n            revert AuthorizationExpired(validBefore);\n        }\n        if (_getEIP3009Storage()._authorizationStates[authorizer][nonce]) {\n            revert AuthorizationAlreadyUsed(authorizer, nonce);\n        }\n    }\n\n    function _markAuthorizationUsed(address authorizer, bytes32 nonce) private {\n        _getEIP3009Storage()._authorizationStates[authorizer][nonce] = true;\n        emit AuthorizationUsed(authorizer, nonce);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.22;\n\nimport {IERC1822Proxiable} from \"../../interfaces/draft-IERC1822.sol\";\nimport {ERC1967Utils} from \"../ERC1967/ERC1967Utils.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * @custom:stateless\n */\nabstract contract UUPSUpgradeable is IERC1822Proxiable {\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address private immutable __self = address(this);\n\n    /**\n     * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`\n     * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,\n     * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.\n     * If the getter returns `\"5.0.0\"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must\n     * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function\n     * during an upgrade.\n     */\n    string public constant UPGRADE_INTERFACE_VERSION = \"5.0.0\";\n\n    /**\n     * @dev The call is from an unauthorized context.\n     */\n    error UUPSUnauthorizedCallContext();\n\n    /**\n     * @dev The storage `slot` is unsupported as a UUID.\n     */\n    error UUPSUnsupportedProxiableUUID(bytes32 slot);\n\n    /**\n     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n     * a proxy contract with an implementation (as defined in ERC-1967) pointing to self. This should only be the case\n     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n     * function through ERC-1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n     * fail.\n     */\n    modifier onlyProxy() {\n        _checkProxy();\n        _;\n    }\n\n    /**\n     * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n     * callable on the implementing contract but not through proxies.\n     */\n    modifier notDelegated() {\n        _checkNotDelegated();\n        _;\n    }\n\n    /**\n     * @dev Implementation of the ERC-1822 {proxiableUUID} function. This returns the storage slot used by the\n     * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n     */\n    function proxiableUUID() external view notDelegated returns (bytes32) {\n        return ERC1967Utils.IMPLEMENTATION_SLOT;\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n     * encoded in `data`.\n     *\n     * Calls {_authorizeUpgrade}.\n     *\n     * Emits an {Upgraded} event.\n     *\n     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n        _authorizeUpgrade(newImplementation);\n        _upgradeToAndCallUUPS(newImplementation, data);\n    }\n\n    /**\n     * @dev Reverts if the execution is not performed via delegatecall or the execution\n     * context is not of a proxy with an ERC-1967 compliant implementation pointing to self.\n     */\n    function _checkProxy() internal view virtual {\n        if (\n            address(this) == __self || // Must be called through delegatecall\n            ERC1967Utils.getImplementation() != __self // Must be called through an active proxy\n        ) {\n            revert UUPSUnauthorizedCallContext();\n        }\n    }\n\n    /**\n     * @dev Reverts if the execution is performed via delegatecall.\n     * See {notDelegated}.\n     */\n    function _checkNotDelegated() internal view virtual {\n        if (address(this) != __self) {\n            // Must not be called through delegatecall\n            revert UUPSUnauthorizedCallContext();\n        }\n    }\n\n    /**\n     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n     * {upgradeToAndCall}.\n     *\n     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n     *\n     * ```solidity\n     * function _authorizeUpgrade(address) internal onlyOwner {}\n     * ```\n     */\n    function _authorizeUpgrade(address newImplementation) internal virtual;\n\n    /**\n     * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.\n     *\n     * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value\n     * is expected to be the implementation slot in ERC-1967.\n     *\n     * Emits an {IERC1967-Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {\n        try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n            if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {\n                revert UUPSUnsupportedProxiableUUID(slot);\n            }\n            ERC1967Utils.upgradeToAndCall(newImplementation, data);\n        } catch {\n            // The implementation is not UUPS\n            revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct Int256Slot {\n        int256 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        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\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        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\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        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport {Initializable} from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/LowLevelCall.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library of low level call functions that implement different calling strategies to deal with the return data.\n *\n * WARNING: Using this library requires an advanced understanding of Solidity and how the EVM works. It is recommended\n * to use the {Address} library instead.\n */\nlibrary LowLevelCall {\n    /// @dev Performs a Solidity function call using a low level `call` and ignoring the return data.\n    function callNoReturn(address target, bytes memory data) internal returns (bool success) {\n        return callNoReturn(target, 0, data);\n    }\n\n    /// @dev Same as {callNoReturn}, but allows to specify the value to be sent in the call.\n    function callNoReturn(address target, uint256 value, bytes memory data) internal returns (bool success) {\n        assembly (\"memory-safe\") {\n            success := call(gas(), target, value, add(data, 0x20), mload(data), 0x00, 0x00)\n        }\n    }\n\n    /// @dev Performs a Solidity function call using a low level `call` and returns the first 64 bytes of the result\n    /// in the scratch space of memory. Useful for functions that return a tuple of single-word values.\n    ///\n    /// WARNING: Do not assume that the results are zero if `success` is false. Memory can be already allocated\n    /// and this function doesn't zero it out.\n    function callReturn64Bytes(\n        address target,\n        bytes memory data\n    ) internal returns (bool success, bytes32 result1, bytes32 result2) {\n        return callReturn64Bytes(target, 0, data);\n    }\n\n    /// @dev Same as {callReturnBytes32Pair}, but allows to specify the value to be sent in the call.\n    function callReturn64Bytes(\n        address target,\n        uint256 value,\n        bytes memory data\n    ) internal returns (bool success, bytes32 result1, bytes32 result2) {\n        assembly (\"memory-safe\") {\n            success := call(gas(), target, value, add(data, 0x20), mload(data), 0x00, 0x40)\n            result1 := mload(0x00)\n            result2 := mload(0x20)\n        }\n    }\n\n    /// @dev Performs a Solidity function call using a low level `staticcall` and ignoring the return data.\n    function staticcallNoReturn(address target, bytes memory data) internal view returns (bool success) {\n        assembly (\"memory-safe\") {\n            success := staticcall(gas(), target, add(data, 0x20), mload(data), 0x00, 0x00)\n        }\n    }\n\n    /// @dev Performs a Solidity function call using a low level `staticcall` and returns the first 64 bytes of the result\n    /// in the scratch space of memory. Useful for functions that return a tuple of single-word values.\n    ///\n    /// WARNING: Do not assume that the results are zero if `success` is false. Memory can be already allocated\n    /// and this function doesn't zero it out.\n    function staticcallReturn64Bytes(\n        address target,\n        bytes memory data\n    ) internal view returns (bool success, bytes32 result1, bytes32 result2) {\n        assembly (\"memory-safe\") {\n            success := staticcall(gas(), target, add(data, 0x20), mload(data), 0x00, 0x40)\n            result1 := mload(0x00)\n            result2 := mload(0x20)\n        }\n    }\n\n    /// @dev Performs a Solidity function call using a low level `delegatecall` and ignoring the return data.\n    function delegatecallNoReturn(address target, bytes memory data) internal returns (bool success) {\n        assembly (\"memory-safe\") {\n            success := delegatecall(gas(), target, add(data, 0x20), mload(data), 0x00, 0x00)\n        }\n    }\n\n    /// @dev Performs a Solidity function call using a low level `delegatecall` and returns the first 64 bytes of the result\n    /// in the scratch space of memory. Useful for functions that return a tuple of single-word values.\n    ///\n    /// WARNING: Do not assume that the results are zero if `success` is false. Memory can be already allocated\n    /// and this function doesn't zero it out.\n    function delegatecallReturn64Bytes(\n        address target,\n        bytes memory data\n    ) internal returns (bool success, bytes32 result1, bytes32 result2) {\n        assembly (\"memory-safe\") {\n            success := delegatecall(gas(), target, add(data, 0x20), mload(data), 0x00, 0x40)\n            result1 := mload(0x00)\n            result2 := mload(0x20)\n        }\n    }\n\n    /// @dev Returns the size of the return data buffer.\n    function returnDataSize() internal pure returns (uint256 size) {\n        assembly (\"memory-safe\") {\n            size := returndatasize()\n        }\n    }\n\n    /// @dev Returns a buffer containing the return data from the last call.\n    function returnData() internal pure returns (bytes memory result) {\n        assembly (\"memory-safe\") {\n            result := mload(0x40)\n            mstore(result, returndatasize())\n            returndatacopy(add(result, 0x20), 0x00, returndatasize())\n            mstore(0x40, add(result, add(0x20, returndatasize())))\n        }\n    }\n\n    /// @dev Revert with the return data from the last call.\n    function bubbleRevert() internal pure {\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            returndatacopy(fmp, 0x00, returndatasize())\n            revert(fmp, returndatasize())\n        }\n    }\n\n    function bubbleRevert(bytes memory returndata) internal pure {\n        assembly (\"memory-safe\") {\n            revert(add(returndata, 0x20), mload(returndata))\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/Address.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\nimport {Errors} from \"./Errors.sol\";\nimport {LowLevelCall} from \"./LowLevelCall.sol\";\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev There's no code at `target` (it is not a contract).\n     */\n    error AddressEmptyCode(address target);\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        if (address(this).balance < amount) {\n            revert Errors.InsufficientBalance(address(this).balance, amount);\n        }\n        if (LowLevelCall.callNoReturn(recipient, amount, \"\")) {\n            // call successful, nothing to do\n            return;\n        } else if (LowLevelCall.returnDataSize() > 0) {\n            LowLevelCall.bubbleRevert();\n        } else {\n            revert Errors.FailedCall();\n        }\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason or custom error, it is bubbled\n     * up by this function (like regular Solidity function calls). However, if\n     * the call reverted with no returned reason, this function reverts with a\n     * {Errors.FailedCall} error.\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        if (address(this).balance < value) {\n            revert Errors.InsufficientBalance(address(this).balance, value);\n        }\n        bool success = LowLevelCall.callNoReturn(target, value, data);\n        if (success && (LowLevelCall.returnDataSize() > 0 || target.code.length > 0)) {\n            return LowLevelCall.returnData();\n        } else if (success) {\n            revert AddressEmptyCode(target);\n        } else if (LowLevelCall.returnDataSize() > 0) {\n            LowLevelCall.bubbleRevert();\n        } else {\n            revert Errors.FailedCall();\n        }\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        bool success = LowLevelCall.staticcallNoReturn(target, data);\n        if (success && (LowLevelCall.returnDataSize() > 0 || target.code.length > 0)) {\n            return LowLevelCall.returnData();\n        } else if (success) {\n            revert AddressEmptyCode(target);\n        } else if (LowLevelCall.returnDataSize() > 0) {\n            LowLevelCall.bubbleRevert();\n        } else {\n            revert Errors.FailedCall();\n        }\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        bool success = LowLevelCall.delegatecallNoReturn(target, data);\n        if (success && (LowLevelCall.returnDataSize() > 0 || target.code.length > 0)) {\n            return LowLevelCall.returnData();\n        } else if (success) {\n            revert AddressEmptyCode(target);\n        } else if (LowLevelCall.returnDataSize() > 0) {\n            LowLevelCall.bubbleRevert();\n        } else {\n            revert Errors.FailedCall();\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n     * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case\n     * of an unsuccessful call.\n     *\n     * NOTE: This function is DEPRECATED and may be removed in the next major release.\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata\n    ) internal view returns (bytes memory) {\n        // only check if target is a contract if the call was successful and the return data is empty\n        // otherwise we already know that it was a contract\n        if (success && (returndata.length > 0 || target.code.length > 0)) {\n            return returndata;\n        } else if (success) {\n            revert AddressEmptyCode(target);\n        } else if (returndata.length > 0) {\n            LowLevelCall.bubbleRevert(returndata);\n        } else {\n            revert Errors.FailedCall();\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n     * revert reason or with a default {Errors.FailedCall} error.\n     */\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else if (returndata.length > 0) {\n            LowLevelCall.bubbleRevert(returndata);\n        } else {\n            revert Errors.FailedCall();\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/cryptography/MessageHashUtils.sol)\n\npragma solidity ^0.8.24;\n\nimport {Strings} from \"../Strings.sol\";\n\n/**\n * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.\n *\n * The library provides methods for generating a hash of a message that conforms to the\n * https://eips.ethereum.org/EIPS/eip-191[ERC-191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]\n * specifications.\n */\nlibrary MessageHashUtils {\n    /**\n     * @dev Returns the keccak256 digest of an ERC-191 signed data with version\n     * `0x45` (`personal_sign` messages).\n     *\n     * The digest is calculated by prefixing a bytes32 `messageHash` with\n     * `\"\\x19Ethereum Signed Message:\\n32\"` and hashing the result. It corresponds with the\n     * hash signed when using the https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign[`eth_sign`] JSON-RPC method.\n     *\n     * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with\n     * keccak256, although any bytes32 value can be safely used because the final digest will\n     * be re-hashed.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\") // 32 is the bytes-length of messageHash\n            mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix\n            digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20)\n        }\n    }\n\n    /**\n     * @dev Returns the keccak256 digest of an ERC-191 signed data with version\n     * `0x45` (`personal_sign` messages).\n     *\n     * The digest is calculated by prefixing an arbitrary `message` with\n     * `\"\\x19Ethereum Signed Message:\\n\" + len(message)` and hashing the result. It corresponds with the\n     * hash signed when using the https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign[`eth_sign`] JSON-RPC method.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {\n        return\n            keccak256(bytes.concat(\"\\x19Ethereum Signed Message:\\n\", bytes(Strings.toString(message.length)), message));\n    }\n\n    /**\n     * @dev Returns the keccak256 digest of an ERC-191 signed data with version\n     * `0x00` (data with intended validator).\n     *\n     * The digest is calculated by prefixing an arbitrary `data` with `\"\\x19\\x00\"` and the intended\n     * `validator` address. Then hashing the result.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(hex\"19_00\", validator, data));\n    }\n\n    /**\n     * @dev Variant of {toDataWithIntendedValidatorHash-address-bytes} optimized for cases where `data` is a bytes32.\n     */\n    function toDataWithIntendedValidatorHash(\n        address validator,\n        bytes32 messageHash\n    ) internal pure returns (bytes32 digest) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, hex\"19_00\")\n            mstore(0x02, shl(96, validator))\n            mstore(0x16, messageHash)\n            digest := keccak256(0x00, 0x36)\n        }\n    }\n\n    /**\n     * @dev Returns the keccak256 digest of an EIP-712 typed data (ERC-191 version `0x01`).\n     *\n     * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with\n     * `\\x19\\x01` and hashing the result. It corresponds to the hash signed by the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            mstore(ptr, hex\"19_01\")\n            mstore(add(ptr, 0x02), domainSeparator)\n            mstore(add(ptr, 0x22), structHash)\n            digest := keccak256(ptr, 0x42)\n        }\n    }\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AccountAlreadyBlacklisted","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AccountBlacklisted","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AccountNotBlacklisted","type":"error"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationAlreadyUsed","type":"error"},{"inputs":[{"internalType":"uint256","name":"validBefore","type":"uint256"}],"name":"AuthorizationExpired","type":"error"},{"inputs":[{"internalType":"uint256","name":"validAfter","type":"uint256"}],"name":"AuthorizationNotYetValid","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"BlacklisterSeizerSeparationViolation","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"BurnExceedsBalance","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"payee","type":"address"}],"name":"CallerMustBePayee","type":"error"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"}],"name":"ERC1967InvalidImplementation","type":"error"},{"inputs":[],"name":"ERC1967NonPayable","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"FailedCall","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"allowance","type":"uint256"}],"name":"InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"recoverer","type":"address"}],"name":"InvalidAssetRecoverer","type":"error"},{"inputs":[],"name":"InvalidAuthorizationSignature","type":"error"},{"inputs":[{"internalType":"address","name":"blacklister","type":"address"}],"name":"InvalidBlacklister","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"InvalidMintAmount","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"InvalidMintDestination","type":"error"},{"inputs":[{"internalType":"address","name":"minterAdmin","type":"address"}],"name":"InvalidMinterAdmin","type":"error"},{"inputs":[],"name":"InvalidMinterAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"pauser","type":"address"}],"name":"InvalidPauser","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"seizer","type":"address"}],"name":"InvalidSeizer","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"InvalidSpender","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"InvalidUpgradeAuthority","type":"error"},{"inputs":[{"internalType":"address","name":"whitelistManager","type":"address"}],"name":"InvalidWhitelistManager","type":"error"},{"inputs":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"MintDestinationAlreadyWhitelisted","type":"error"},{"inputs":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"MintDestinationNotWhitelisted","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"allowance","type":"uint256"}],"name":"MintExceedsAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"MinterAllowanceNotZero","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"MinterWhitelistManagerSeparationViolation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NotAssetRecoverer","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NotBlacklister","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NotMinter","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NotMinterAdmin","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NotPauser","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NotSeizer","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NotUpgradeAuthority","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NotWhitelistManager","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"PermitExpired","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"SeizeAmountExceedsBalance","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"}],"name":"SeizeFromNotBlacklisted","type":"error"},{"inputs":[],"name":"SeizeFromZeroAddress","type":"error"},{"inputs":[],"name":"SeizeToZeroAddress","type":"error"},{"inputs":[],"name":"UUPSUnauthorizedCallContext","type":"error"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"name":"UUPSUnsupportedProxiableUUID","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"UpgradeAuthorityOwnerSeparationViolation","type":"error"},{"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":true,"internalType":"address","name":"tokenContract","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AssetRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousRecoverer","type":"address"},{"indexed":true,"internalType":"address","name":"newRecoverer","type":"address"}],"name":"AssetRecovererChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationUsed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"Blacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousBlacklister","type":"address"},{"indexed":true,"internalType":"address","name":"newBlacklister","type":"address"}],"name":"BlacklisterChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"burner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","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":true,"internalType":"address","name":"minter","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MintDestinationUnwhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MintDestinationWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousMinterAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"newMinterAdmin","type":"address"}],"name":"MinterAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"minterAllowedAmount","type":"uint256"}],"name":"MinterConfigured","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"}],"name":"MinterRemoved","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":"address","name":"previousPauser","type":"address"},{"indexed":true,"internalType":"address","name":"newPauser","type":"address"}],"name":"PauserChanged","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":"amount","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"trackId","type":"bytes32"}],"name":"Seized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousSeizer","type":"address"},{"indexed":true,"internalType":"address","name":"newSeizer","type":"address"}],"name":"SeizerChanged","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":true,"internalType":"address","name":"account","type":"address"}],"name":"UnBlacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousUpgradeAuthority","type":"address"},{"indexed":true,"internalType":"address","name":"newUpgradeAuthority","type":"address"}],"name":"UpgradeAuthorityChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousWhitelistManager","type":"address"},{"indexed":true,"internalType":"address","name":"newWhitelistManager","type":"address"}],"name":"WhitelistManagerChanged","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPGRADE_INTERFACE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"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":[{"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":[{"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":[],"name":"assetRecoverer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"authorizationState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"blacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"blacklistBulk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blacklister","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"uint256","name":"allowance_","type":"uint256"}],"name":"configureMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currency","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","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":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"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":"tokenName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"string","name":"tokenCurrency","type":"string"},{"internalType":"uint8","name":"tokenDecimals","type":"uint8"},{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"address","name":"initialPauser","type":"address"},{"internalType":"address","name":"initialBlacklister","type":"address"},{"internalType":"address","name":"initialAssetRecoverer","type":"address"},{"internalType":"address","name":"initialSeizer","type":"address"},{"internalType":"address","name":"initialMinterAdmin","type":"address"},{"internalType":"address","name":"initialWhitelistManager","type":"address"},{"internalType":"address","name":"initialUpgradeAuthority","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"isMintWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minterAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"minterAllowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[],"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":"pauser","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"removeMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"trackId","type":"bytes32"}],"name":"seize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"seizer","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","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":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"unBlacklistBulk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"unwhitelistMintDestination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRecoverer","type":"address"}],"name":"updateAssetRecoverer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newBlacklister","type":"address"}],"name":"updateBlacklister","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMinterAdmin","type":"address"}],"name":"updateMinterAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPauser","type":"address"}],"name":"updatePauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSeizer","type":"address"}],"name":"updateSeizer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newUpgradeAuthority","type":"address"}],"name":"updateUpgradeAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newWhitelistManager","type":"address"}],"name":"updateWhitelistManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upgradeAuthority","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"whitelistManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"whitelistMintDestination","outputs":[],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":null}