creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/utils/OnlyOwnerMulticaller.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {Ownable} from \"solady/src/auth/Ownable.sol\";\n\n/**\n * @title OnlyOwnerMulticaller\n * @author vectorized.eth\n * @notice A fork of vectorized's Multicaller that can only be called by the owner.\n *         Contract that allows for efficient aggregation\n *         of multiple calls in a single transaction.\n */\ncontract OnlyOwnerMulticaller is Ownable {\n    constructor(address owner) {\n        _initializeOwner(owner);\n    }\n\n    // =============================================================\n    //                            ERRORS\n    // =============================================================\n\n    /**\n     * @dev The lengths of the input arrays are not the same.\n     */\n    error ArrayLengthsMismatch();\n\n    // =============================================================\n    //                    AGGREGATION OPERATIONS\n    // =============================================================\n\n    /**\n     * @dev Aggregates multiple calls in a single transaction.\n     * @param targets  An array of addresses to call.\n     * @param data     An array of calldata to forward to the targets.\n     * @param values   How much ETH to forward to each target.\n     * @param refundTo The address to transfer any remaining ETH in the contract after the calls.\n     *                 If `address(0)`, remaining ETH will NOT be refunded.\n     *                 If `address(1)`, remaining ETH will be refunded to `msg.sender`.\n     *                 If anything else, remaining ETH will be refunded to `refundTo`.\n     * @return An array of the returndata from each call.\n     */\n    function aggregate(\n        address[] calldata targets,\n        bytes[] calldata data,\n        uint256[] calldata values,\n        address refundTo\n    ) external payable onlyOwner returns (bytes[] memory) {\n        assembly {\n            if iszero(\n                and(\n                    eq(targets.length, data.length),\n                    eq(data.length, values.length)\n                )\n            ) {\n                // Store the function selector of `ArrayLengthsMismatch()`.\n                mstore(returndatasize(), 0x3b800a46)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n\n            let resultsSize := 0x40\n\n            if data.length {\n                let results := 0x40\n                // Left shift by 5 is equivalent to multiplying by 0x20.\n                data.length := shl(5, data.length)\n                // Copy the offsets from calldata into memory.\n                calldatacopy(results, data.offset, data.length)\n                // Offset into `results`.\n                let resultsOffset := data.length\n                // Pointer to the end of `results`.\n                let end := add(results, data.length)\n                // For deriving the calldata offsets from the `results` pointer.\n                let valuesOffsetDiff := sub(values.offset, results)\n                let targetsOffsetDiff := sub(targets.offset, results)\n\n                for {\n\n                } 1 {\n\n                } {\n                    // The offset of the current bytes in the calldata.\n                    let o := add(data.offset, mload(results))\n                    let memPtr := add(resultsOffset, 0x40)\n                    // Copy the current bytes from calldata to the memory.\n                    calldatacopy(\n                        memPtr,\n                        add(o, 0x20), // The offset of the current bytes' bytes.\n                        calldataload(o) // The length of the current bytes.\n                    )\n                    if iszero(\n                        call(\n                            gas(), // Remaining gas.\n                            calldataload(add(targetsOffsetDiff, results)), // Address to call.\n                            calldataload(add(valuesOffsetDiff, results)), // ETH to send.\n                            memPtr, // Start of input calldata in memory.\n                            calldataload(o), // Size of input calldata.\n                            0x00, // We will use returndatacopy instead.\n                            0x00 // We will use returndatacopy instead.\n                        )\n                    ) {\n                        // Bubble up the revert if the call reverts.\n                        returndatacopy(0x00, 0x00, returndatasize())\n                        revert(0x00, returndatasize())\n                    }\n                    // Append the current `resultsOffset` into `results`.\n                    mstore(results, resultsOffset)\n                    // Append the returndatasize, and the returndata.\n                    mstore(memPtr, returndatasize())\n                    returndatacopy(add(memPtr, 0x20), 0x00, returndatasize())\n                    // Advance the `resultsOffset` by `returndatasize() + 0x20`,\n                    // rounded up to the next multiple of 0x20.\n                    resultsOffset := and(\n                        add(add(resultsOffset, returndatasize()), 0x3f),\n                        not(0x1f)\n                    )\n                    // Advance the `results` pointer.\n                    results := add(results, 0x20)\n                    if eq(results, end) {\n                        break\n                    }\n                }\n                resultsSize := add(resultsOffset, 0x40)\n            }\n\n            if refundTo {\n                // Force transfers all the remaining ETH in the contract to `refundTo`,\n                // with a gas stipend of 100000, which should be enough for most use cases.\n                // If sending via a regular call fails, force sends the ETH by\n                // creating a temporary contract which uses `SELFDESTRUCT` to force send the ETH.\n                if selfbalance() {\n                    // If `refundTo` is `address(1)`, replace it with the `msg.sender`.\n                    refundTo := xor(\n                        refundTo,\n                        mul(eq(refundTo, 1), xor(refundTo, caller()))\n                    )\n                    // Transfer the ETH and check if it succeeded or not.\n                    if iszero(\n                        call(\n                            100000,\n                            refundTo,\n                            selfbalance(),\n                            codesize(),\n                            0x00,\n                            codesize(),\n                            0x00\n                        )\n                    ) {\n                        mstore(0x00, refundTo) // Store the address in scratch space.\n                        mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n                        mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n                        // We can directly use `SELFDESTRUCT` in the contract creation.\n                        // Compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758\n                        if iszero(create(selfbalance(), 0x0b, 0x16)) {\n                            // Coerce gas estimation to provide enough gas for the `create` above.\n                            revert(codesize(), codesize())\n                        }\n                    }\n                }\n            }\n\n            mstore(0x00, 0x20) // Store the memory offset of the `results`.\n            mstore(0x20, targets.length) // Store `targets.length` into `results`.\n            // Direct return.\n            return(0x00, resultsSize)\n        }\n    }\n\n    /**\n     * @dev For receiving ETH.\n     *      Does nothing and returns nothing.\n     */\n    receive() external payable {}\n}\n"
      },
      "lib/solady/src/auth/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)\n///\n/// @dev Note:\n/// This implementation does NOT auto-initialize the owner to `msg.sender`.\n/// You MUST call the `_initializeOwner` in the constructor / initializer.\n///\n/// While the ownable portion follows\n/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,\n/// the nomenclature for the 2-step ownership handover may be unique to this codebase.\nabstract contract Ownable {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The caller is not authorized to call the function.\n    error Unauthorized();\n\n    /// @dev The `newOwner` cannot be the zero address.\n    error NewOwnerIsZeroAddress();\n\n    /// @dev The `pendingOwner` does not have a valid handover request.\n    error NoHandoverRequest();\n\n    /// @dev Cannot double-initialize.\n    error AlreadyInitialized();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.\n    /// This event is intentionally kept the same as OpenZeppelin's Ownable to be\n    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),\n    /// despite it not being as lightweight as a single argument event.\n    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);\n\n    /// @dev An ownership handover to `pendingOwner` has been requested.\n    event OwnershipHandoverRequested(address indexed pendingOwner);\n\n    /// @dev The ownership handover to `pendingOwner` has been canceled.\n    event OwnershipHandoverCanceled(address indexed pendingOwner);\n\n    /// @dev `keccak256(bytes(\"OwnershipTransferred(address,address)\"))`.\n    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =\n        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;\n\n    /// @dev `keccak256(bytes(\"OwnershipHandoverRequested(address)\"))`.\n    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =\n        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;\n\n    /// @dev `keccak256(bytes(\"OwnershipHandoverCanceled(address)\"))`.\n    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =\n        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The owner slot is given by:\n    /// `bytes32(~uint256(uint32(bytes4(keccak256(\"_OWNER_SLOT_NOT\")))))`.\n    /// It is intentionally chosen to be a high value\n    /// to avoid collision with lower slots.\n    /// The choice of manual storage layout is to enable compatibility\n    /// with both regular and upgradeable contracts.\n    bytes32 internal constant _OWNER_SLOT =\n        0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;\n\n    /// The ownership handover slot of `newOwner` is given by:\n    /// ```\n    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))\n    ///     let handoverSlot := keccak256(0x00, 0x20)\n    /// ```\n    /// It stores the expiry timestamp of the two-step ownership handover.\n    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     INTERNAL FUNCTIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Override to return true to make `_initializeOwner` prevent double-initialization.\n    function _guardInitializeOwner() internal pure virtual returns (bool guard) {}\n\n    /// @dev Initializes the owner directly without authorization guard.\n    /// This function must be called upon initialization,\n    /// regardless of whether the contract is upgradeable or not.\n    /// This is to enable generalization to both regular and upgradeable contracts,\n    /// and to save gas in case the initial owner is not the caller.\n    /// For performance reasons, this function will not check if there\n    /// is an existing owner.\n    function _initializeOwner(address newOwner) internal virtual {\n        if (_guardInitializeOwner()) {\n            /// @solidity memory-safe-assembly\n            assembly {\n                let ownerSlot := _OWNER_SLOT\n                if sload(ownerSlot) {\n                    mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.\n                    revert(0x1c, 0x04)\n                }\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Store the new value.\n                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)\n            }\n        } else {\n            /// @solidity memory-safe-assembly\n            assembly {\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Store the new value.\n                sstore(_OWNER_SLOT, newOwner)\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)\n            }\n        }\n    }\n\n    /// @dev Sets the owner directly without authorization guard.\n    function _setOwner(address newOwner) internal virtual {\n        if (_guardInitializeOwner()) {\n            /// @solidity memory-safe-assembly\n            assembly {\n                let ownerSlot := _OWNER_SLOT\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)\n                // Store the new value.\n                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))\n            }\n        } else {\n            /// @solidity memory-safe-assembly\n            assembly {\n                let ownerSlot := _OWNER_SLOT\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)\n                // Store the new value.\n                sstore(ownerSlot, newOwner)\n            }\n        }\n    }\n\n    /// @dev Throws if the sender is not the owner.\n    function _checkOwner() internal view virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // If the caller is not the stored owner, revert.\n            if iszero(eq(caller(), sload(_OWNER_SLOT))) {\n                mstore(0x00, 0x82b42900) // `Unauthorized()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n\n    /// @dev Returns how long a two-step ownership handover is valid for in seconds.\n    /// Override to return a different value if needed.\n    /// Made internal to conserve bytecode. Wrap it in a public function if needed.\n    function _ownershipHandoverValidFor() internal view virtual returns (uint64) {\n        return 48 * 3600;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  PUBLIC UPDATE FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Allows the owner to transfer the ownership to `newOwner`.\n    function transferOwnership(address newOwner) public payable virtual onlyOwner {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(shl(96, newOwner)) {\n                mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.\n                revert(0x1c, 0x04)\n            }\n        }\n        _setOwner(newOwner);\n    }\n\n    /// @dev Allows the owner to renounce their ownership.\n    function renounceOwnership() public payable virtual onlyOwner {\n        _setOwner(address(0));\n    }\n\n    /// @dev Request a two-step ownership handover to the caller.\n    /// The request will automatically expire in 48 hours (172800 seconds) by default.\n    function requestOwnershipHandover() public payable virtual {\n        unchecked {\n            uint256 expires = block.timestamp + _ownershipHandoverValidFor();\n            /// @solidity memory-safe-assembly\n            assembly {\n                // Compute and set the handover slot to `expires`.\n                mstore(0x0c, _HANDOVER_SLOT_SEED)\n                mstore(0x00, caller())\n                sstore(keccak256(0x0c, 0x20), expires)\n                // Emit the {OwnershipHandoverRequested} event.\n                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())\n            }\n        }\n    }\n\n    /// @dev Cancels the two-step ownership handover to the caller, if any.\n    function cancelOwnershipHandover() public payable virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute and set the handover slot to 0.\n            mstore(0x0c, _HANDOVER_SLOT_SEED)\n            mstore(0x00, caller())\n            sstore(keccak256(0x0c, 0x20), 0)\n            // Emit the {OwnershipHandoverCanceled} event.\n            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())\n        }\n    }\n\n    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.\n    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.\n    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute and set the handover slot to 0.\n            mstore(0x0c, _HANDOVER_SLOT_SEED)\n            mstore(0x00, pendingOwner)\n            let handoverSlot := keccak256(0x0c, 0x20)\n            // If the handover does not exist, or has expired.\n            if gt(timestamp(), sload(handoverSlot)) {\n                mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.\n                revert(0x1c, 0x04)\n            }\n            // Set the handover slot to 0.\n            sstore(handoverSlot, 0)\n        }\n        _setOwner(pendingOwner);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   PUBLIC READ FUNCTIONS                    */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the owner of the contract.\n    function owner() public view virtual returns (address result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := sload(_OWNER_SLOT)\n        }\n    }\n\n    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.\n    function ownershipHandoverExpiresAt(address pendingOwner)\n        public\n        view\n        virtual\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the handover slot.\n            mstore(0x0c, _HANDOVER_SLOT_SEED)\n            mstore(0x00, pendingOwner)\n            // Load the handover slot.\n            result := sload(keccak256(0x0c, 0x20))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         MODIFIERS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Marks a function as only callable by the owner.\n    modifier onlyOwner() virtual {\n        _checkOwner();\n        _;\n    }\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@openzeppelin/=lib/openzeppelin-contracts/contracts/",
        "account-abstraction/=lib/account-abstraction/contracts/",
        "solady/=lib/solady/",
        "smart-wallet/=lib/smart-wallet/",
        "magic-spend/=lib/magic-spend/",
        "multicaller/=lib/multicaller/",
        "v2-core/=lib/v2-core/",
        "v2-periphery/=lib/v2-periphery/",
        "permit2/=lib/permit2/",
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "@openzeppelin/contracts/security/=lib/magic-spend/lib/openzeppelin-contracts/contracts/utils/",
        "FreshCryptoLib/=lib/smart-wallet/lib/FreshCryptoLib/solidity/src/",
        "Multicaller/=lib/Multicaller/src/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
        "forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/",
        "forge-std/=lib/forge-std/src/",
        "fuzzlib/=lib/magic-spend/lib/fuzzlib/src/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "p256-verifier/=lib/smart-wallet/lib/p256-verifier/",
        "solmate/=lib/permit2/lib/solmate/",
        "webauthn-sol/=lib/smart-wallet/lib/webauthn-sol/src/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": true,
      "libraries": {}
    }
  }}