creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/Dagon.sol": {
        "content": "// ᗪᗩGOᑎ 𒀭 𒀭 𒀭 𒀭 𒀭 𒀭 𒀭 𒀭 𒀭 𒀭 𒀭\n// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.24;\n\nimport {ERC6909} from \"@solady/src/tokens/ERC6909.sol\";\nimport {SignatureCheckerLib} from \"@solady/src/utils/SignatureCheckerLib.sol\";\n\n/// @notice Simple ownership singleton for smart accounts. Version 1.\ncontract Dagon is ERC6909 {\n    /// ======================= CUSTOM ERRORS ======================= ///\n\n    /// @dev Inputs are invalid for an ownership setting.\n    error InvalidSetting();\n\n    /// =========================== EVENTS =========================== ///\n\n    /// @dev Logs new authority contract for an account.\n    event AuthSet(address indexed account, IAuth auth);\n\n    /// @dev Logs new token uri settings for an account.\n    event URISet(address indexed account, string uri);\n\n    /// @dev Logs new ownership threshold for an account.\n    event ThresholdSet(address indexed account, uint88 threshold);\n\n    /// @dev Logs new token ownership standard for an account.\n    event TokenSet(address indexed account, address token, Standard standard);\n\n    /// ========================== STRUCTS ========================== ///\n\n    /// @dev The account token metadata struct.\n    struct Metadata {\n        string name;\n        string symbol;\n        string tokenURI;\n        IAuth authority;\n        uint96 totalSupply;\n    }\n\n    /// @dev The account ownership shares struct.\n    struct Ownership {\n        address owner;\n        uint96 shares;\n    }\n\n    /// @dev The account ownership settings struct.\n    struct Settings {\n        address token;\n        uint88 threshold;\n        Standard standard;\n    }\n\n    /// @dev The packed ERC4337 user operation (userOp) struct.\n    struct PackedUserOperation {\n        address sender;\n        uint256 nonce;\n        bytes initCode;\n        bytes callData;\n        bytes32 accountGasLimits;\n        uint256 preVerificationGas;\n        bytes32 gasFees; // `maxPriorityFee` and `maxFeePerGas`.\n        bytes paymasterAndData;\n        bytes signature;\n    }\n\n    /// =========================== ENUMS =========================== ///\n\n    /// @dev The token standard interface enum.\n    enum Standard {\n        DAGON,\n        ERC20,\n        ERC721,\n        ERC1155,\n        ERC6909\n    }\n\n    /// ========================== STORAGE ========================== ///\n\n    /// @dev Stores mapping of metadata settings to account token IDs.\n    /// note: IDs are unique to addresses (`uint256(uint160(account))`).\n    mapping(uint256 id => Metadata) internal _metadata;\n\n    /// @dev Stores mapping of ownership settings to accounts.\n    mapping(address account => Settings) internal _settings;\n\n    /// @dev Stores mapping of voting tallies to signed userOp hashes.\n    mapping(bytes32 signedHash => uint256) public votingTally;\n\n    /// @dev Stores mapping of account owner voting shares cast on signed userOp hashes.\n    mapping(address owner => mapping(bytes32 signedHash => uint256 shares)) public voted;\n\n    /// ================= ERC6909 METADATA & SUPPLY ================= ///\n\n    /// @dev Returns the name for token `id` using this contract.\n    function name(uint256 id) public view virtual override(ERC6909) returns (string memory) {\n        return _metadata[id].name;\n    }\n\n    /// @dev Returns the symbol for token `id` using this contract.\n    function symbol(uint256 id) public view virtual override(ERC6909) returns (string memory) {\n        return _metadata[id].symbol;\n    }\n\n    /// @dev Returns the URI for token `id` using this contract.\n    function tokenURI(uint256 id) public view virtual override(ERC6909) returns (string memory) {\n        return _metadata[id].tokenURI;\n    }\n\n    /// @dev Returns the total supply for token `id` using this contract.\n    function totalSupply(uint256 id) public view virtual returns (uint256) {\n        return _metadata[id].totalSupply;\n    }\n\n    /// ======================== CONSTRUCTOR ======================== ///\n\n    /// @dev Constructs\n    /// this implementation.\n    constructor() payable {}\n\n    /// =================== VALIDATION OPERATIONS =================== ///\n\n    /// @dev Validates ERC1271 signature with additional auth logic flow among owners.\n    /// note: This implementation is designed to be the ERC-173-owner-of-4337-accounts.\n    function isValidSignature(bytes32 hash, bytes calldata signature)\n        public\n        view\n        virtual\n        returns (bytes4)\n    {\n        Settings memory set = _settings[msg.sender];\n        if (signature.length != 0) {\n            unchecked {\n                uint256 pos;\n                address prev;\n                address owner;\n                uint256 tally;\n                for (uint256 i; i != signature.length / 85; ++i) {\n                    if (\n                        SignatureCheckerLib.isValidSignatureNowCalldata(\n                            owner = address(bytes20(signature[pos:pos + 20])),\n                            hash,\n                            signature[pos + 20:pos + 85]\n                        ) && prev < owner // Check double voting.\n                    ) {\n                        pos += 85;\n                        prev = owner;\n                        tally += set.standard == Standard.DAGON\n                            ? balanceOf(owner, uint256(uint160(msg.sender)))\n                            : set.standard == Standard.ERC20 || set.standard == Standard.ERC721\n                                ? _balanceOf(set.token, owner)\n                                : _balanceOf(set.token, owner, uint256(uint160(msg.sender)));\n                    } else {\n                        return 0xffffffff; // Failure code.\n                    }\n                }\n                return _validateReturn(tally >= set.threshold);\n            }\n        }\n        return _validateReturn(votingTally[hash] >= set.threshold);\n    }\n\n    /// @dev Validates packed userOp with additional auth logic flow among owners.\n    /// note: This is expected to be called in a validator plugin-like userOp flow.\n    function validateUserOp(\n        PackedUserOperation calldata userOp,\n        bytes32 userOpHash,\n        uint256 /*missingAccountFunds*/\n    ) public payable virtual returns (uint256 validationData) {\n        IAuth auth = _metadata[uint256(uint160(msg.sender))].authority;\n        if (auth != IAuth(address(0))) {\n            (address target, uint256 value, bytes memory data) =\n                abi.decode(userOp.callData[4:], (address, uint256, bytes));\n            auth.validateCall(msg.sender, target, value, data);\n        }\n        if (\n            isValidSignature(\n                SignatureCheckerLib.toEthSignedMessageHash(userOpHash), userOp.signature\n            ) != this.isValidSignature.selector\n        ) validationData = 0x01; // Failure code.\n    }\n\n    /// @dev Returns validated signature result within the conventional ERC1271 syntax.\n    function _validateReturn(bool success) internal pure virtual returns (bytes4 result) {\n        assembly (\"memory-safe\") {\n            // `success ? bytes4(keccak256(\"isValidSignature(bytes32,bytes)\")) : 0xffffffff`.\n            result := shl(224, or(0x1626ba7e, sub(0, iszero(success))))\n        }\n    }\n\n    /// ===================== VOTING OPERATIONS ===================== ///\n\n    /// @dev Casts account owner voting shares on a given ERC4337 userOp hash.\n    function vote(address account, bytes32 userOpHash, bytes calldata signature)\n        public\n        payable\n        virtual\n        returns (uint256)\n    {\n        Settings memory set = _settings[account];\n        bytes32 hash = SignatureCheckerLib.toEthSignedMessageHash(userOpHash);\n        unchecked {\n            uint256 pos;\n            address owner;\n            uint256 tally;\n            for (uint256 i; i != signature.length / 85; ++i) {\n                if (\n                    SignatureCheckerLib.isValidSignatureNowCalldata(\n                        owner = address(bytes20(signature[pos:pos + 20])),\n                        hash,\n                        signature[pos + 20:pos + 85]\n                    ) && voted[owner][hash] == 0 // Check double voting.\n                ) {\n                    pos += 85;\n                    tally += voted[owner][hash] = set.standard == Standard.DAGON\n                        ? balanceOf(owner, uint256(uint160(account)))\n                        : set.standard == Standard.ERC20 || set.standard == Standard.ERC721\n                            ? _balanceOf(set.token, owner)\n                            : _balanceOf(set.token, owner, uint256(uint160(account)));\n                }\n            }\n            return votingTally[hash] += tally; // Return latest total tally.\n        }\n    }\n\n    /// ======================== INSTALLATION ======================== ///\n\n    /// @dev Initializes ownership settings for the caller account.\n    /// note: Finalizes with transfer request in two-step pattern.\n    /// See, e.g., Ownable.sol:\n    /// https://github.com/Vectorized/solady/blob/main/src/auth/Ownable.sol\n    function install(Ownership[] calldata owners, Settings calldata setting, Metadata calldata meta)\n        public\n        payable\n        virtual\n    {\n        uint256 id = uint256(uint160(msg.sender));\n        if (owners.length != 0) {\n            uint96 supply;\n            for (uint256 i; i != owners.length;) {\n                supply += owners[i].shares;\n                _mint(owners[i].owner, id, owners[i].shares);\n                unchecked {\n                    ++i;\n                }\n            }\n            _metadata[id].totalSupply += supply;\n        }\n        setToken(setting.token, setting.standard);\n        setThreshold(setting.threshold);\n        if (bytes(meta.name).length != 0) {\n            _metadata[id].name = meta.name;\n            _metadata[id].symbol = meta.symbol;\n        }\n        if (bytes(meta.tokenURI).length != 0) setURI(meta.tokenURI);\n        if (meta.authority != IAuth(address(0))) _metadata[id].authority = meta.authority;\n        try IOwnable(msg.sender).requestOwnershipHandover() {} catch {} // Avoid revert.\n    }\n\n    /// ===================== OWNERSHIP SETTINGS ===================== ///\n\n    /// @dev Returns the account settings.\n    function getSettings(address account) public view virtual returns (address, uint88, Standard) {\n        Settings storage set = _settings[account];\n        return (set.token, set.threshold, set.standard);\n    }\n\n    /// @dev Sets new authority contract for the caller account.\n    function setAuth(IAuth auth) public payable virtual {\n        emit AuthSet(msg.sender, (_metadata[uint256(uint160(msg.sender))].authority = auth));\n    }\n\n    /// @dev Sets new token ownership interface standard for the caller account.\n    function setToken(address token, Standard standard) public payable virtual {\n        emit TokenSet(\n            msg.sender,\n            _settings[msg.sender].token = token,\n            _settings[msg.sender].standard = standard\n        );\n    }\n\n    /// @dev Sets new ownership threshold for the caller account.\n    function setThreshold(uint88 threshold) public payable virtual {\n        Settings storage set = _settings[msg.sender];\n        if (\n            threshold\n                > (\n                    set.standard == Standard.DAGON\n                        ? totalSupply(uint256(uint160(msg.sender)))\n                        : set.standard == Standard.ERC20 || set.standard == Standard.ERC721\n                            ? _totalSupply(set.token)\n                            : _totalSupply(set.token, uint256(uint160(msg.sender)))\n                ) || threshold == 0\n        ) revert InvalidSetting();\n        emit ThresholdSet(msg.sender, (set.threshold = threshold));\n    }\n\n    /// ====================== TOKEN OPERATIONS ====================== ///\n\n    /// @dev Returns the account metadata.\n    function getMetadata(address account)\n        public\n        view\n        virtual\n        returns (string memory, string memory, string memory, IAuth)\n    {\n        Metadata storage meta = _metadata[uint256(uint160(account))];\n        return (meta.name, meta.symbol, meta.tokenURI, meta.authority);\n    }\n\n    /// @dev Mints shares for an owner of the caller account.\n    function mint(address owner, uint96 shares) public payable virtual {\n        uint256 id = uint256(uint160(msg.sender));\n        _metadata[id].totalSupply += shares;\n        _mint(owner, id, shares);\n    }\n\n    /// @dev Burns shares from an owner of the caller account.\n    function burn(address owner, uint96 shares) public payable virtual {\n        uint256 id = uint256(uint160(msg.sender));\n        unchecked {\n            if (_settings[msg.sender].threshold > (_metadata[id].totalSupply -= shares)) {\n                revert InvalidSetting();\n            }\n        }\n        _burn(owner, id, shares);\n    }\n\n    /// @dev Sets new token URI metadata for the caller account.\n    function setURI(string calldata uri) public payable virtual {\n        emit URISet(msg.sender, (_metadata[uint256(uint160(msg.sender))].tokenURI = uri));\n    }\n\n    /// =================== EXTERNAL TOKEN HELPERS =================== ///\n\n    /// @dev Returns the amount of ERC20/721 `token` owned by `account`.\n    function _balanceOf(address token, address account)\n        internal\n        view\n        virtual\n        returns (uint256 amount)\n    {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.\n            mstore(0x14, account) // Store the `account` argument.\n            pop(staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20))\n            amount := mload(0x20)\n        }\n    }\n\n    /// @dev Returns the amount of ERC1155/6909 `token` `id` owned by `account`.\n    function _balanceOf(address token, address account, uint256 id)\n        internal\n        view\n        virtual\n        returns (uint256 amount)\n    {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x00fdd58e000000000000000000000000) // `balanceOf(address,uint256)`.\n            mstore(0x14, account) // Store the `account` argument.\n            mstore(0x34, id) // Store the `id` argument.\n            pop(staticcall(gas(), token, 0x10, 0x44, 0x20, 0x20))\n            amount := mload(0x20)\n            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n        }\n    }\n\n    /// @dev Returns the total supply of ERC20/721 `token`.\n    function _totalSupply(address token) internal view virtual returns (uint256 supply) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x18160ddd) // `totalSupply()`.\n            pop(staticcall(gas(), token, 0x1c, 0x04, 0x20, 0x20))\n            supply := mload(0x20)\n        }\n    }\n\n    /// @dev Returns the total supply of ERC1155/6909 `token` `id`.\n    function _totalSupply(address token, uint256 id)\n        internal\n        view\n        virtual\n        returns (uint256 supply)\n    {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0xbd85b039) // `totalSupply(uint256)`.\n            mstore(0x20, id) // Store the `id` argument.\n            pop(staticcall(gas(), token, 0x1c, 0x24, 0x20, 0x20))\n            supply := mload(0x20)\n        }\n    }\n\n    /// ========================= OVERRIDES ========================= ///\n\n    /// @dev Hook that is called before any transfer of tokens.\n    /// This includes minting and burning. Also requests authority for token transfers.\n    function _beforeTokenTransfer(address from, address to, uint256 id, uint256 amount)\n        internal\n        virtual\n        override(ERC6909)\n    {\n        IAuth auth = _metadata[id].authority;\n        if (auth != IAuth(address(0))) auth.validateTransfer(from, to, id, amount);\n    }\n}\n\n/// @notice Simple authority interface for contracts.\ninterface IAuth {\n    function validateTransfer(address, address, uint256, uint256)\n        external\n        payable\n        returns (uint256);\n    function validateCall(address, address, uint256, bytes calldata)\n        external\n        payable\n        returns (uint256);\n}\n\n/// @notice Simple ownership interface for handover requests.\ninterface IOwnable {\n    function requestOwnershipHandover() external payable;\n}\n"
      },
      "lib/solady/src/tokens/ERC6909.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Simple EIP-6909 implementation.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC6909.sol)\n///\n/// @dev Note:\n/// The ERC6909 standard allows minting and transferring to and from the zero address,\n/// minting and transferring zero tokens, as well as self-approvals.\n/// For performance, this implementation WILL NOT revert for such actions.\n/// Please add any checks with overrides if desired.\n///\n/// If you are overriding:\n/// - Make sure all variables written to storage are properly cleaned\n//    (e.g. the bool value for `isOperator` MUST be either 1 or 0 under the hood).\n/// - Check that the overridden function is actually used in the function you want to\n///   change the behavior of. Much of the code has been manually inlined for performance.\nabstract contract ERC6909 {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Insufficient balance.\n    error InsufficientBalance();\n\n    /// @dev Insufficient permission to perform the action.\n    error InsufficientPermission();\n\n    /// @dev The balance has overflowed.\n    error BalanceOverflow();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Emitted when `by` transfers `amount` of token `id` from `from` to `to`.\n    event Transfer(\n        address by, address indexed from, address indexed to, uint256 indexed id, uint256 amount\n    );\n\n    /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens.\n    event OperatorSet(address indexed owner, address indexed operator, bool approved);\n\n    /// @dev Emitted when `owner` approves `spender` to use `amount` of `id` token.\n    event Approval(\n        address indexed owner, address indexed spender, uint256 indexed id, uint256 amount\n    );\n\n    /// @dev `keccak256(bytes(\"Transfer(address,address,address,uint256,uint256)\"))`.\n    uint256 private constant _TRANSFER_EVENT_SIGNATURE =\n        0x1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac728859;\n\n    /// @dev `keccak256(bytes(\"OperatorSet(address,address,bool)\"))`.\n    uint256 private constant _OPERATOR_SET_EVENT_SIGNATURE =\n        0xceb576d9f15e4e200fdb5096d64d5dfd667e16def20c1eefd14256d8e3faa267;\n\n    /// @dev `keccak256(bytes(\"Approval(address,address,uint256,uint256)\"))`.\n    uint256 private constant _APPROVAL_EVENT_SIGNATURE =\n        0xb3fd5071835887567a0671151121894ddccc2842f1d10bedad13e0d17cace9a7;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The `ownerSlotSeed` of a given owner is given by.\n    /// ```\n    ///     let ownerSlotSeed := or(_ERC6909_MASTER_SLOT_SEED, shl(96, owner))\n    /// ```\n    ///\n    /// The balance slot of `owner` is given by.\n    /// ```\n    ///     mstore(0x20, ownerSlotSeed)\n    ///     mstore(0x00, id)\n    ///     let balanceSlot := keccak256(0x00, 0x40)\n    /// ```\n    ///\n    /// The operator approval slot of `owner` is given by.\n    /// ```\n    ///     mstore(0x20, ownerSlotSeed)\n    ///     mstore(0x00, operator)\n    ///     let operatorApprovalSlot := keccak256(0x0c, 0x34)\n    /// ```\n    ///\n    /// The allowance slot of (`owner`, `spender`, `id`) is given by:\n    /// ```\n    ///     mstore(0x34, ownerSlotSeed)\n    ///     mstore(0x14, spender)\n    ///     mstore(0x00, id)\n    ///     let allowanceSlot := keccak256(0x00, 0x54)\n    /// ```\n    uint256 private constant _ERC6909_MASTER_SLOT_SEED = 0xedcaa89a82293940;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      ERC6909 METADATA                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the name for token `id`.\n    function name(uint256 id) public view virtual returns (string memory);\n\n    /// @dev Returns the symbol for token `id`.\n    function symbol(uint256 id) public view virtual returns (string memory);\n\n    /// @dev Returns the number of decimals for token `id`.\n    /// Returns 18 by default.\n    /// Please override this function if you need to return a custom value.\n    function decimals(uint256 id) public view virtual returns (uint8) {\n        id = id; // Silence compiler warning.\n        return 18;\n    }\n\n    /// @dev Returns the Uniform Resource Identifier (URI) for token `id`.\n    function tokenURI(uint256 id) public view virtual returns (string memory);\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          ERC6909                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the amount of token `id` owned by `owner`.\n    function balanceOf(address owner, uint256 id) public view virtual returns (uint256 amount) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x20, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x14, owner)\n            mstore(0x00, id)\n            amount := sload(keccak256(0x00, 0x40))\n        }\n    }\n\n    /// @dev Returns the amount of token `id` that `spender` can spend on behalf of `owner`.\n    function allowance(address owner, address spender, uint256 id)\n        public\n        view\n        virtual\n        returns (uint256 amount)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x34, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x28, owner)\n            mstore(0x14, spender)\n            mstore(0x00, id)\n            amount := sload(keccak256(0x00, 0x54))\n            // Restore the part of the free memory pointer that has been overwritten.\n            mstore(0x34, 0x00)\n        }\n    }\n\n    /// @dev Checks if a `spender` is approved by `owner` to manage all of their tokens.\n    function isOperator(address owner, address spender) public view virtual returns (bool status) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x20, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x14, owner)\n            mstore(0x00, spender)\n            status := sload(keccak256(0x0c, 0x34))\n        }\n    }\n\n    /// @dev Transfers `amount` of token `id` from the caller to `to`.\n    ///\n    /// Requirements:\n    /// - caller must at least have `amount`.\n    ///\n    /// Emits a {Transfer} event.\n    function transfer(address to, uint256 id, uint256 amount)\n        public\n        payable\n        virtual\n        returns (bool)\n    {\n        _beforeTokenTransfer(msg.sender, to, id, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            /// Compute the balance slot and load its value.\n            mstore(0x20, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x14, caller())\n            mstore(0x00, id)\n            let fromBalanceSlot := keccak256(0x00, 0x40)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Compute the balance slot of `to`.\n            mstore(0x14, to)\n            mstore(0x00, id)\n            let toBalanceSlot := keccak256(0x00, 0x40)\n            let toBalanceBefore := sload(toBalanceSlot)\n            let toBalanceAfter := add(toBalanceBefore, amount)\n            // Revert if the balance overflows.\n            if lt(toBalanceAfter, toBalanceBefore) {\n                mstore(0x00, 0x89560ca1) // `BalanceOverflow()`.\n                revert(0x1c, 0x04)\n            }\n            // Store the updated balance of `to`.\n            sstore(toBalanceSlot, toBalanceAfter)\n            // Emit the {Transfer} event.\n            mstore(0x00, caller())\n            mstore(0x20, amount)\n            log4(0x00, 0x40, _TRANSFER_EVENT_SIGNATURE, caller(), shr(96, shl(96, to)), id)\n        }\n        _afterTokenTransfer(msg.sender, to, id, amount);\n        return true;\n    }\n\n    /// @dev Transfers `amount` of token `id` from `from` to `to`.\n    ///\n    /// Note: Does not update the allowance if it is the maximum uint256 value.\n    ///\n    /// Requirements:\n    /// - `from` must at least have `amount` of token `id`.\n    /// -  The caller must have at least `amount` of allowance to transfer the\n    ///    tokens of `from` or approved as an operator.\n    ///\n    /// Emits a {Transfer} event.\n    function transferFrom(address from, address to, uint256 id, uint256 amount)\n        public\n        payable\n        virtual\n        returns (bool)\n    {\n        _beforeTokenTransfer(from, to, id, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the operator slot and load its value.\n            mstore(0x34, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x28, from)\n            mstore(0x14, caller())\n            // Check if the caller is an operator.\n            if iszero(sload(keccak256(0x20, 0x34))) {\n                // Compute the allowance slot and load its value.\n                mstore(0x00, id)\n                let allowanceSlot := keccak256(0x00, 0x54)\n                let allowance_ := sload(allowanceSlot)\n                // If the allowance is not the maximum uint256 value.\n                if add(allowance_, 1) {\n                    // Revert if the amount to be transferred exceeds the allowance.\n                    if gt(amount, allowance_) {\n                        mstore(0x00, 0xdeda9030) // `InsufficientPermission()`.\n                        revert(0x1c, 0x04)\n                    }\n                    // Subtract and store the updated allowance.\n                    sstore(allowanceSlot, sub(allowance_, amount))\n                }\n            }\n            // Compute the balance slot and load its value.\n            mstore(0x14, id)\n            let fromBalanceSlot := keccak256(0x14, 0x40)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Compute the balance slot of `to`.\n            mstore(0x28, to)\n            mstore(0x14, id)\n            let toBalanceSlot := keccak256(0x14, 0x40)\n            let toBalanceBefore := sload(toBalanceSlot)\n            let toBalanceAfter := add(toBalanceBefore, amount)\n            // Revert if the balance overflows.\n            if lt(toBalanceAfter, toBalanceBefore) {\n                mstore(0x00, 0x89560ca1) // `BalanceOverflow()`.\n                revert(0x1c, 0x04)\n            }\n            // Store the updated balance of `to`.\n            sstore(toBalanceSlot, toBalanceAfter)\n            // Emit the {Transfer} event.\n            mstore(0x00, caller())\n            mstore(0x20, amount)\n            // forgefmt: disable-next-line\n            log4(0x00, 0x40, _TRANSFER_EVENT_SIGNATURE, shr(96, shl(96, from)), shr(96, shl(96, to)), id)\n            // Restore the part of the free memory pointer that has been overwritten.\n            mstore(0x34, 0x00)\n        }\n        _afterTokenTransfer(from, to, id, amount);\n        return true;\n    }\n\n    /// @dev Sets `amount` as the allowance of `spender` for the caller for token `id`.\n    ///\n    /// Emits a {Approval} event.\n    function approve(address spender, uint256 id, uint256 amount)\n        public\n        payable\n        virtual\n        returns (bool)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the allowance slot and store the amount.\n            mstore(0x34, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x28, caller())\n            mstore(0x14, spender)\n            mstore(0x00, id)\n            sstore(keccak256(0x00, 0x54), amount)\n            // Emit the {Approval} event.\n            mstore(0x00, amount)\n            log4(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, caller(), shr(96, mload(0x20)), id)\n            // Restore the part of the free memory pointer that has been overwritten.\n            mstore(0x34, 0x00)\n        }\n        return true;\n    }\n\n    ///  @dev Sets whether `operator` is approved to manage the tokens of the caller.\n    ///\n    /// Emits {OperatorSet} event.\n    function setOperator(address operator, bool approved) public payable virtual returns (bool) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Convert `approved` to `0` or `1`.\n            let approvedCleaned := iszero(iszero(approved))\n            // Compute the operator slot and store the approved.\n            mstore(0x20, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x14, caller())\n            mstore(0x00, operator)\n            sstore(keccak256(0x0c, 0x34), approvedCleaned)\n            // Emit the {OperatorSet} event.\n            mstore(0x20, approvedCleaned)\n            log3(0x20, 0x20, _OPERATOR_SET_EVENT_SIGNATURE, caller(), shr(96, mload(0x0c)))\n        }\n        return true;\n    }\n\n    /// @dev Returns true if this contract implements the interface defined by `interfaceId`.\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let s := shr(224, interfaceId)\n            // ERC165: 0x01ffc9a7, ERC6909: 0x0f632fb3.\n            result := or(eq(s, 0x01ffc9a7), eq(s, 0x0f632fb3))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     INTERNAL FUNCTIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Mints `amount` of token `id` to `to`.\n    ///\n    /// Emits a {Transfer} event.\n    function _mint(address to, uint256 id, uint256 amount) internal virtual {\n        _beforeTokenTransfer(address(0), to, id, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the balance slot.\n            mstore(0x20, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x14, to)\n            mstore(0x00, id)\n            let toBalanceSlot := keccak256(0x00, 0x40)\n            // Add and store the updated balance\n            let toBalanceBefore := sload(toBalanceSlot)\n            let toBalanceAfter := add(toBalanceBefore, amount)\n            // Revert if the balance overflows.\n            if lt(toBalanceAfter, toBalanceBefore) {\n                mstore(0x00, 0x89560ca1) // `BalanceOverflow()`.\n                revert(0x1c, 0x04)\n            }\n            sstore(toBalanceSlot, toBalanceAfter)\n            // Emit the {Transfer} event.\n            mstore(0x00, caller())\n            mstore(0x20, amount)\n            log4(0x00, 0x40, _TRANSFER_EVENT_SIGNATURE, 0, shr(96, shl(96, to)), id)\n        }\n        _afterTokenTransfer(address(0), to, id, amount);\n    }\n\n    /// @dev Burns `amount` token `id` from `from`.\n    ///\n    /// Emits a {Transfer} event.\n    function _burn(address from, uint256 id, uint256 amount) internal virtual {\n        _beforeTokenTransfer(from, address(0), id, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the balance slot.\n            mstore(0x20, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x14, from)\n            mstore(0x00, id)\n            let fromBalanceSlot := keccak256(0x00, 0x40)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Emit the {Transfer} event.\n            mstore(0x00, caller())\n            mstore(0x20, amount)\n            log4(0x00, 0x40, _TRANSFER_EVENT_SIGNATURE, shr(96, shl(96, from)), 0, id)\n        }\n        _afterTokenTransfer(from, address(0), id, amount);\n    }\n\n    /// @dev Transfers `amount` of token `id` from `from` to `to`.\n    ///\n    /// Note: Does not update the allowance if it is the maximum uint256 value.\n    ///\n    /// Requirements:\n    /// - `from` must at least have `amount` of token `id`.\n    /// - If `by` is not the zero address,\n    ///   it must have at least `amount` of allowance to transfer the\n    ///   tokens of `from` or approved as an operator.\n    ///\n    /// Emits a {Transfer} event.\n    function _transfer(address by, address from, address to, uint256 id, uint256 amount)\n        internal\n        virtual\n    {\n        _beforeTokenTransfer(from, to, id, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let bitmaskAddress := 0xffffffffffffffffffffffffffffffffffffffff\n            // Compute the operator slot and load its value.\n            mstore(0x34, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x28, from)\n            // If `by` is not the zero address.\n            if and(bitmaskAddress, by) {\n                mstore(0x14, by)\n                // Check if the `by` is an operator.\n                if iszero(sload(keccak256(0x20, 0x34))) {\n                    // Compute the allowance slot and load its value.\n                    mstore(0x00, id)\n                    let allowanceSlot := keccak256(0x00, 0x54)\n                    let allowance_ := sload(allowanceSlot)\n                    // If the allowance is not the maximum uint256 value.\n                    if add(allowance_, 1) {\n                        // Revert if the amount to be transferred exceeds the allowance.\n                        if gt(amount, allowance_) {\n                            mstore(0x00, 0xdeda9030) // `InsufficientPermission()`.\n                            revert(0x1c, 0x04)\n                        }\n                        // Subtract and store the updated allowance.\n                        sstore(allowanceSlot, sub(allowance_, amount))\n                    }\n                }\n            }\n            // Compute the balance slot and load its value.\n            mstore(0x14, id)\n            let fromBalanceSlot := keccak256(0x14, 0x40)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Compute the balance slot of `to`.\n            mstore(0x28, to)\n            mstore(0x14, id)\n            let toBalanceSlot := keccak256(0x14, 0x40)\n            let toBalanceBefore := sload(toBalanceSlot)\n            let toBalanceAfter := add(toBalanceBefore, amount)\n            // Revert if the balance overflows.\n            if lt(toBalanceAfter, toBalanceBefore) {\n                mstore(0x00, 0x89560ca1) // `BalanceOverflow()`.\n                revert(0x1c, 0x04)\n            }\n            // Store the updated balance of `to`.\n            sstore(toBalanceSlot, toBalanceAfter)\n            // Emit the {Transfer} event.\n            mstore(0x00, and(bitmaskAddress, by))\n            mstore(0x20, amount)\n            // forgefmt: disable-next-line\n            log4(0x00, 0x40, _TRANSFER_EVENT_SIGNATURE, and(bitmaskAddress, from), and(bitmaskAddress, to), id)\n            // Restore the part of the free memory pointer that has been overwritten.\n            mstore(0x34, 0x00)\n        }\n        _afterTokenTransfer(from, to, id, amount);\n    }\n\n    /// @dev Sets `amount` as the allowance of `spender` for `owner` for token `id`.\n    ///\n    /// Emits a {Approval} event.\n    function _approve(address owner, address spender, uint256 id, uint256 amount)\n        internal\n        virtual\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the allowance slot and store the amount.\n            mstore(0x34, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x28, owner)\n            mstore(0x14, spender)\n            mstore(0x00, id)\n            sstore(keccak256(0x00, 0x54), amount)\n            // Emit the {Approval} event.\n            mstore(0x00, amount)\n            // forgefmt: disable-next-line\n            log4(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, shr(96, mload(0x34)), shr(96, mload(0x20)), id)\n            // Restore the part of the free memory pointer that has been overwritten.\n            mstore(0x34, 0x00)\n        }\n    }\n\n    ///  @dev Sets whether `operator` is approved to manage the tokens of `owner`.\n    ///\n    /// Emits {OperatorSet} event.\n    function _setOperator(address owner, address operator, bool approved) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Convert `approved` to `0` or `1`.\n            let approvedCleaned := iszero(iszero(approved))\n            // Compute the operator slot and store the approved.\n            mstore(0x20, _ERC6909_MASTER_SLOT_SEED)\n            mstore(0x14, owner)\n            mstore(0x00, operator)\n            sstore(keccak256(0x0c, 0x34), approvedCleaned)\n            // Emit the {OperatorSet} event.\n            mstore(0x20, approvedCleaned)\n            // forgefmt: disable-next-line\n            log3(0x20, 0x20, _OPERATOR_SET_EVENT_SIGNATURE, shr(96, shl(96, owner)), shr(96, mload(0x0c)))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     HOOKS TO OVERRIDE                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Hook that is called before any transfer of tokens.\n    /// This includes minting and burning.\n    function _beforeTokenTransfer(address from, address to, uint256 id, uint256 amount)\n        internal\n        virtual\n    {}\n\n    /// @dev Hook that is called after any transfer of tokens.\n    /// This includes minting and burning.\n    function _afterTokenTransfer(address from, address to, uint256 id, uint256 amount)\n        internal\n        virtual\n    {}\n}\n"
      },
      "lib/solady/src/utils/SignatureCheckerLib.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Signature verification helper that supports both ECDSA signatures from EOAs\n/// and ERC1271 signatures from smart contract wallets like Argent and Gnosis safe.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SignatureCheckerLib.sol)\n/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/SignatureChecker.sol)\n///\n/// @dev Note:\n/// - The signature checking functions use the ecrecover precompile (0x1).\n/// - The `bytes memory signature` variants use the identity precompile (0x4)\n///   to copy memory internally.\n/// - Unlike ECDSA signatures, contract signatures are revocable.\n/// - As of Solady version 0.0.134, all `bytes signature` variants accept both\n///   regular 65-byte `(r, s, v)` and EIP-2098 `(r, vs)` short form signatures.\n///   See: https://eips.ethereum.org/EIPS/eip-2098\n///   This is for calldata efficiency on smart accounts prevalent on L2s.\n///\n/// WARNING! Do NOT use signatures as unique identifiers:\n/// - Use a nonce in the digest to prevent replay attacks on the same contract.\n/// - Use EIP-712 for the digest to prevent replay attacks across different chains and contracts.\n///   EIP-712 also enables readable signing of typed data for better user safety.\n/// This implementation does NOT check if a signature is non-malleable.\nlibrary SignatureCheckerLib {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*               SIGNATURE CHECKING OPERATIONS                */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns whether `signature` is valid for `signer` and `hash`.\n    /// If `signer` is a smart contract, the signature is validated with ERC1271.\n    /// Otherwise, the signature is validated with `ECDSA.recover`.\n    function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature)\n        internal\n        view\n        returns (bool isValid)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clean the upper 96 bits of `signer` in case they are dirty.\n            for { signer := shr(96, shl(96, signer)) } signer {} {\n                let m := mload(0x40)\n                mstore(0x00, hash)\n                mstore(0x40, mload(add(signature, 0x20))) // `r`.\n                if eq(mload(signature), 64) {\n                    let vs := mload(add(signature, 0x40))\n                    mstore(0x20, add(shr(255, vs), 27)) // `v`.\n                    mstore(0x60, shr(1, shl(1, vs))) // `s`.\n                    let t :=\n                        staticcall(\n                            gas(), // Amount of gas left for the transaction.\n                            1, // Address of `ecrecover`.\n                            0x00, // Start of input.\n                            0x80, // Size of input.\n                            0x01, // Start of output.\n                            0x20 // Size of output.\n                        )\n                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n                    if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {\n                        isValid := 1\n                        mstore(0x60, 0) // Restore the zero slot.\n                        mstore(0x40, m) // Restore the free memory pointer.\n                        break\n                    }\n                }\n                if eq(mload(signature), 65) {\n                    mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`.\n                    mstore(0x60, mload(add(signature, 0x40))) // `s`.\n                    let t :=\n                        staticcall(\n                            gas(), // Amount of gas left for the transaction.\n                            1, // Address of `ecrecover`.\n                            0x00, // Start of input.\n                            0x80, // Size of input.\n                            0x01, // Start of output.\n                            0x20 // Size of output.\n                        )\n                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n                    if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {\n                        isValid := 1\n                        mstore(0x60, 0) // Restore the zero slot.\n                        mstore(0x40, m) // Restore the free memory pointer.\n                        break\n                    }\n                }\n                mstore(0x60, 0) // Restore the zero slot.\n                mstore(0x40, m) // Restore the free memory pointer.\n\n                let f := shl(224, 0x1626ba7e)\n                mstore(m, f) // `bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))`.\n                mstore(add(m, 0x04), hash)\n                let d := add(m, 0x24)\n                mstore(d, 0x40) // The offset of the `signature` in the calldata.\n                // Copy the `signature` over.\n                let n := add(0x20, mload(signature))\n                pop(staticcall(gas(), 4, signature, n, add(m, 0x44), n))\n                // forgefmt: disable-next-item\n                isValid := and(\n                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).\n                    eq(mload(d), f),\n                    // Whether the staticcall does not revert.\n                    // This must be placed at the end of the `and` clause,\n                    // as the arguments are evaluated from right to left.\n                    staticcall(\n                        gas(), // Remaining gas.\n                        signer, // The `signer` address.\n                        m, // Offset of calldata in memory.\n                        add(returndatasize(), 0x44), // Length of calldata in memory.\n                        d, // Offset of returndata.\n                        0x20 // Length of returndata to write.\n                    )\n                )\n                break\n            }\n        }\n    }\n\n    /// @dev Returns whether `signature` is valid for `signer` and `hash`.\n    /// If `signer` is a smart contract, the signature is validated with ERC1271.\n    /// Otherwise, the signature is validated with `ECDSA.recover`.\n    function isValidSignatureNowCalldata(address signer, bytes32 hash, bytes calldata signature)\n        internal\n        view\n        returns (bool isValid)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clean the upper 96 bits of `signer` in case they are dirty.\n            for { signer := shr(96, shl(96, signer)) } signer {} {\n                let m := mload(0x40)\n                mstore(0x00, hash)\n                if eq(signature.length, 64) {\n                    let vs := calldataload(add(signature.offset, 0x20))\n                    mstore(0x20, add(shr(255, vs), 27)) // `v`.\n                    mstore(0x40, calldataload(signature.offset)) // `r`.\n                    mstore(0x60, shr(1, shl(1, vs))) // `s`.\n                    let t :=\n                        staticcall(\n                            gas(), // Amount of gas left for the transaction.\n                            1, // Address of `ecrecover`.\n                            0x00, // Start of input.\n                            0x80, // Size of input.\n                            0x01, // Start of output.\n                            0x20 // Size of output.\n                        )\n                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n                    if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {\n                        isValid := 1\n                        mstore(0x60, 0) // Restore the zero slot.\n                        mstore(0x40, m) // Restore the free memory pointer.\n                        break\n                    }\n                }\n                if eq(signature.length, 65) {\n                    mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`.\n                    calldatacopy(0x40, signature.offset, 0x40) // `r`, `s`.\n                    let t :=\n                        staticcall(\n                            gas(), // Amount of gas left for the transaction.\n                            1, // Address of `ecrecover`.\n                            0x00, // Start of input.\n                            0x80, // Size of input.\n                            0x01, // Start of output.\n                            0x20 // Size of output.\n                        )\n                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n                    if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {\n                        isValid := 1\n                        mstore(0x60, 0) // Restore the zero slot.\n                        mstore(0x40, m) // Restore the free memory pointer.\n                        break\n                    }\n                }\n                mstore(0x60, 0) // Restore the zero slot.\n                mstore(0x40, m) // Restore the free memory pointer.\n\n                let f := shl(224, 0x1626ba7e)\n                mstore(m, f) // `bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))`.\n                mstore(add(m, 0x04), hash)\n                let d := add(m, 0x24)\n                mstore(d, 0x40) // The offset of the `signature` in the calldata.\n                mstore(add(m, 0x44), signature.length)\n                // Copy the `signature` over.\n                calldatacopy(add(m, 0x64), signature.offset, signature.length)\n                // forgefmt: disable-next-item\n                isValid := and(\n                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).\n                    eq(mload(d), f),\n                    // Whether the staticcall does not revert.\n                    // This must be placed at the end of the `and` clause,\n                    // as the arguments are evaluated from right to left.\n                    staticcall(\n                        gas(), // Remaining gas.\n                        signer, // The `signer` address.\n                        m, // Offset of calldata in memory.\n                        add(signature.length, 0x64), // Length of calldata in memory.\n                        d, // Offset of returndata.\n                        0x20 // Length of returndata to write.\n                    )\n                )\n                break\n            }\n        }\n    }\n\n    /// @dev Returns whether the signature (`r`, `vs`) is valid for `signer` and `hash`.\n    /// If `signer` is a smart contract, the signature is validated with ERC1271.\n    /// Otherwise, the signature is validated with `ECDSA.recover`.\n    function isValidSignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs)\n        internal\n        view\n        returns (bool isValid)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clean the upper 96 bits of `signer` in case they are dirty.\n            for { signer := shr(96, shl(96, signer)) } signer {} {\n                let m := mload(0x40)\n                mstore(0x00, hash)\n                mstore(0x20, add(shr(255, vs), 27)) // `v`.\n                mstore(0x40, r) // `r`.\n                mstore(0x60, shr(1, shl(1, vs))) // `s`.\n                let t :=\n                    staticcall(\n                        gas(), // Amount of gas left for the transaction.\n                        1, // Address of `ecrecover`.\n                        0x00, // Start of input.\n                        0x80, // Size of input.\n                        0x01, // Start of output.\n                        0x20 // Size of output.\n                    )\n                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n                if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {\n                    isValid := 1\n                    mstore(0x60, 0) // Restore the zero slot.\n                    mstore(0x40, m) // Restore the free memory pointer.\n                    break\n                }\n\n                let f := shl(224, 0x1626ba7e)\n                mstore(m, f) // `bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))`.\n                mstore(add(m, 0x04), hash)\n                let d := add(m, 0x24)\n                mstore(d, 0x40) // The offset of the `signature` in the calldata.\n                mstore(add(m, 0x44), 65) // Length of the signature.\n                mstore(add(m, 0x64), r) // `r`.\n                mstore(add(m, 0x84), mload(0x60)) // `s`.\n                mstore8(add(m, 0xa4), mload(0x20)) // `v`.\n                // forgefmt: disable-next-item\n                isValid := and(\n                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).\n                    eq(mload(d), f),\n                    // Whether the staticcall does not revert.\n                    // This must be placed at the end of the `and` clause,\n                    // as the arguments are evaluated from right to left.\n                    staticcall(\n                        gas(), // Remaining gas.\n                        signer, // The `signer` address.\n                        m, // Offset of calldata in memory.\n                        0xa5, // Length of calldata in memory.\n                        d, // Offset of returndata.\n                        0x20 // Length of returndata to write.\n                    )\n                )\n                mstore(0x60, 0) // Restore the zero slot.\n                mstore(0x40, m) // Restore the free memory pointer.\n                break\n            }\n        }\n    }\n\n    /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `signer` and `hash`.\n    /// If `signer` is a smart contract, the signature is validated with ERC1271.\n    /// Otherwise, the signature is validated with `ECDSA.recover`.\n    function isValidSignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s)\n        internal\n        view\n        returns (bool isValid)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clean the upper 96 bits of `signer` in case they are dirty.\n            for { signer := shr(96, shl(96, signer)) } signer {} {\n                let m := mload(0x40)\n                mstore(0x00, hash)\n                mstore(0x20, and(v, 0xff)) // `v`.\n                mstore(0x40, r) // `r`.\n                mstore(0x60, s) // `s`.\n                let t :=\n                    staticcall(\n                        gas(), // Amount of gas left for the transaction.\n                        1, // Address of `ecrecover`.\n                        0x00, // Start of input.\n                        0x80, // Size of input.\n                        0x01, // Start of output.\n                        0x20 // Size of output.\n                    )\n                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.\n                if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {\n                    isValid := 1\n                    mstore(0x60, 0) // Restore the zero slot.\n                    mstore(0x40, m) // Restore the free memory pointer.\n                    break\n                }\n\n                let f := shl(224, 0x1626ba7e)\n                mstore(m, f) // `bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))`.\n                mstore(add(m, 0x04), hash)\n                let d := add(m, 0x24)\n                mstore(d, 0x40) // The offset of the `signature` in the calldata.\n                mstore(add(m, 0x44), 65) // Length of the signature.\n                mstore(add(m, 0x64), r) // `r`.\n                mstore(add(m, 0x84), s) // `s`.\n                mstore8(add(m, 0xa4), v) // `v`.\n                // forgefmt: disable-next-item\n                isValid := and(\n                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).\n                    eq(mload(d), f),\n                    // Whether the staticcall does not revert.\n                    // This must be placed at the end of the `and` clause,\n                    // as the arguments are evaluated from right to left.\n                    staticcall(\n                        gas(), // Remaining gas.\n                        signer, // The `signer` address.\n                        m, // Offset of calldata in memory.\n                        0xa5, // Length of calldata in memory.\n                        d, // Offset of returndata.\n                        0x20 // Length of returndata to write.\n                    )\n                )\n                mstore(0x60, 0) // Restore the zero slot.\n                mstore(0x40, m) // Restore the free memory pointer.\n                break\n            }\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     ERC1271 OPERATIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns whether `signature` is valid for `hash` for an ERC1271 `signer` contract.\n    function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes memory signature)\n        internal\n        view\n        returns (bool isValid)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40)\n            let f := shl(224, 0x1626ba7e)\n            mstore(m, f) // `bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))`.\n            mstore(add(m, 0x04), hash)\n            let d := add(m, 0x24)\n            mstore(d, 0x40) // The offset of the `signature` in the calldata.\n            // Copy the `signature` over.\n            let n := add(0x20, mload(signature))\n            pop(staticcall(gas(), 4, signature, n, add(m, 0x44), n))\n            // forgefmt: disable-next-item\n            isValid := and(\n                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).\n                eq(mload(d), f),\n                // Whether the staticcall does not revert.\n                // This must be placed at the end of the `and` clause,\n                // as the arguments are evaluated from right to left.\n                staticcall(\n                    gas(), // Remaining gas.\n                    signer, // The `signer` address.\n                    m, // Offset of calldata in memory.\n                    add(returndatasize(), 0x44), // Length of calldata in memory.\n                    d, // Offset of returndata.\n                    0x20 // Length of returndata to write.\n                )\n            )\n        }\n    }\n\n    /// @dev Returns whether `signature` is valid for `hash` for an ERC1271 `signer` contract.\n    function isValidERC1271SignatureNowCalldata(\n        address signer,\n        bytes32 hash,\n        bytes calldata signature\n    ) internal view returns (bool isValid) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40)\n            let f := shl(224, 0x1626ba7e)\n            mstore(m, f) // `bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))`.\n            mstore(add(m, 0x04), hash)\n            let d := add(m, 0x24)\n            mstore(d, 0x40) // The offset of the `signature` in the calldata.\n            mstore(add(m, 0x44), signature.length)\n            // Copy the `signature` over.\n            calldatacopy(add(m, 0x64), signature.offset, signature.length)\n            // forgefmt: disable-next-item\n            isValid := and(\n                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).\n                eq(mload(d), f),\n                // Whether the staticcall does not revert.\n                // This must be placed at the end of the `and` clause,\n                // as the arguments are evaluated from right to left.\n                staticcall(\n                    gas(), // Remaining gas.\n                    signer, // The `signer` address.\n                    m, // Offset of calldata in memory.\n                    add(signature.length, 0x64), // Length of calldata in memory.\n                    d, // Offset of returndata.\n                    0x20 // Length of returndata to write.\n                )\n            )\n        }\n    }\n\n    /// @dev Returns whether the signature (`r`, `vs`) is valid for `hash`\n    /// for an ERC1271 `signer` contract.\n    function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs)\n        internal\n        view\n        returns (bool isValid)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40)\n            let f := shl(224, 0x1626ba7e)\n            mstore(m, f) // `bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))`.\n            mstore(add(m, 0x04), hash)\n            let d := add(m, 0x24)\n            mstore(d, 0x40) // The offset of the `signature` in the calldata.\n            mstore(add(m, 0x44), 65) // Length of the signature.\n            mstore(add(m, 0x64), r) // `r`.\n            mstore(add(m, 0x84), shr(1, shl(1, vs))) // `s`.\n            mstore8(add(m, 0xa4), add(shr(255, vs), 27)) // `v`.\n            // forgefmt: disable-next-item\n            isValid := and(\n                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).\n                eq(mload(d), f),\n                // Whether the staticcall does not revert.\n                // This must be placed at the end of the `and` clause,\n                // as the arguments are evaluated from right to left.\n                staticcall(\n                    gas(), // Remaining gas.\n                    signer, // The `signer` address.\n                    m, // Offset of calldata in memory.\n                    0xa5, // Length of calldata in memory.\n                    d, // Offset of returndata.\n                    0x20 // Length of returndata to write.\n                )\n            )\n        }\n    }\n\n    /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `hash`\n    /// for an ERC1271 `signer` contract.\n    function isValidERC1271SignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s)\n        internal\n        view\n        returns (bool isValid)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40)\n            let f := shl(224, 0x1626ba7e)\n            mstore(m, f) // `bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))`.\n            mstore(add(m, 0x04), hash)\n            let d := add(m, 0x24)\n            mstore(d, 0x40) // The offset of the `signature` in the calldata.\n            mstore(add(m, 0x44), 65) // Length of the signature.\n            mstore(add(m, 0x64), r) // `r`.\n            mstore(add(m, 0x84), s) // `s`.\n            mstore8(add(m, 0xa4), v) // `v`.\n            // forgefmt: disable-next-item\n            isValid := and(\n                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).\n                eq(mload(d), f),\n                // Whether the staticcall does not revert.\n                // This must be placed at the end of the `and` clause,\n                // as the arguments are evaluated from right to left.\n                staticcall(\n                    gas(), // Remaining gas.\n                    signer, // The `signer` address.\n                    m, // Offset of calldata in memory.\n                    0xa5, // Length of calldata in memory.\n                    d, // Offset of returndata.\n                    0x20 // Length of returndata to write.\n                )\n            )\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     HASHING OPERATIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns an Ethereum Signed Message, created from a `hash`.\n    /// This produces a hash corresponding to the one signed with the\n    /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign)\n    /// JSON-RPC method as part of EIP-191.\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x20, hash) // Store into scratch space for keccak256.\n            mstore(0x00, \"\\x00\\x00\\x00\\x00\\x19Ethereum Signed Message:\\n32\") // 28 bytes.\n            result := keccak256(0x04, 0x3c) // `32 * 2 - (32 - 28) = 60 = 0x3c`.\n        }\n    }\n\n    /// @dev Returns an Ethereum Signed Message, created from `s`.\n    /// This produces a hash corresponding to the one signed with the\n    /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign)\n    /// JSON-RPC method as part of EIP-191.\n    /// Note: Supports lengths of `s` up to 999999 bytes.\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let sLength := mload(s)\n            let o := 0x20\n            mstore(o, \"\\x19Ethereum Signed Message:\\n\") // 26 bytes, zero-right-padded.\n            mstore(0x00, 0x00)\n            // Convert the `s.length` to ASCII decimal representation: `base10(s.length)`.\n            for { let temp := sLength } 1 {} {\n                o := sub(o, 1)\n                mstore8(o, add(48, mod(temp, 10)))\n                temp := div(temp, 10)\n                if iszero(temp) { break }\n            }\n            let n := sub(0x3a, o) // Header length: `26 + 32 - o`.\n            // Throw an out-of-offset error (consumes all gas) if the header exceeds 32 bytes.\n            returndatacopy(returndatasize(), returndatasize(), gt(n, 0x20))\n            mstore(s, or(mload(0x00), mload(n))) // Temporarily store the header.\n            result := keccak256(add(s, sub(0x20, n)), add(n, sLength))\n            mstore(s, sLength) // Restore the length.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   EMPTY CALLDATA HELPERS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns an empty calldata bytes.\n    function emptySignature() internal pure returns (bytes calldata signature) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            signature.length := 0\n        }\n    }\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@solady/=lib/solady/",
        "@forge/=lib/forge-std/src/",
        "forge-std/=lib/forge-std/src/",
        "solady/=lib/solady/src/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 9999999
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "abi"
          ]
        }
      },
      "evmVersion": "shanghai",
      "viaIR": true,
      "libraries": {}
    }
  }}