creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/quark-factory/src/QuarkFactory.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\nimport {CodeJar} from \"codejar/src/CodeJar.sol\";\nimport {QuarkWallet} from \"quark-core/src/QuarkWallet.sol\";\nimport {QuarkStateManager} from \"quark-core/src/QuarkStateManager.sol\";\nimport {QuarkWalletProxyFactory} from \"quark-proxy/src/QuarkWalletProxyFactory.sol\";\nimport {BatchExecutor} from \"quark-core/src/periphery/BatchExecutor.sol\";\n\n/**\n * @title Quark Factory\n * @notice A factory for deploying all Quark related contracts to deterministic addresses\n * @author Compound Labs, Inc.\n */\ncontract QuarkFactory {\n    CodeJar public immutable codeJar;\n    QuarkWallet public quarkWalletImpl;\n    QuarkWalletProxyFactory public quarkWalletProxyFactory;\n    QuarkStateManager public quarkStateManager;\n    BatchExecutor public batchExecutor;\n\n    constructor(CodeJar codeJar_) {\n        codeJar = codeJar_;\n    }\n\n    function deployQuarkContracts() external {\n        quarkStateManager =\n            QuarkStateManager(payable(codeJar.saveCode(abi.encodePacked(type(QuarkStateManager).creationCode))));\n        quarkWalletImpl = QuarkWallet(\n            payable(\n                codeJar.saveCode(\n                    abi.encodePacked(type(QuarkWallet).creationCode, abi.encode(codeJar, quarkStateManager))\n                )\n            )\n        );\n        quarkWalletProxyFactory = QuarkWalletProxyFactory(\n            payable(\n                codeJar.saveCode(\n                    abi.encodePacked(type(QuarkWalletProxyFactory).creationCode, abi.encode(quarkWalletImpl))\n                )\n            )\n        );\n        batchExecutor = BatchExecutor(payable(codeJar.saveCode(abi.encodePacked(type(BatchExecutor).creationCode))));\n    }\n}\n"
      },
      "src/codejar/src/CodeJar.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\n/**\n * @title Code Jar\n * @notice Deploys contract code to deterministic addresses\n * @author Compound Labs, Inc.\n */\ncontract CodeJar {\n    /**\n     * @notice Deploys the code via Code Jar, no-op if it already exists\n     * @dev This call is meant to be idemponent and fairly inexpensive on a second call\n     * @param code The creation bytecode of the code to save\n     * @return The address of the contract that matches the input code's contructor output\n     */\n    function saveCode(bytes memory code) external returns (address) {\n        address codeAddress = getCodeAddress(code);\n\n        if (codeAddress.code.length > 0) {\n            // Code is already deployed\n            return codeAddress;\n        } else {\n            // The code has not been deployed here (or it was deployed and destructed).\n            address script;\n            assembly {\n                script := create2(0, add(code, 0x20), mload(code), 0)\n            }\n\n            // Posit: these cannot fail and are purely defense-in-depth\n            require(script == codeAddress);\n\n            uint256 scriptSz;\n            assembly {\n                scriptSz := extcodesize(script)\n            }\n\n            // Disallow the empty code and self-destructing constructors\n            // Note: Script can still self-destruct after being deployed until Dencun\n            require(scriptSz > 0);\n\n            return codeAddress;\n        }\n    }\n\n    /**\n     * @notice Checks if code was already deployed by CodeJar\n     * @param code The runtime bytecode of the code to check\n     * @return True if code already exists in Code Jar\n     */\n    function codeExists(bytes calldata code) external view returns (bool) {\n        address codeAddress = getCodeAddress(code);\n\n        return codeAddress.code.length > 0;\n    }\n\n    /**\n     * @dev Returns the create2 address based on the creation code\n     * @return The create2 address to deploy this code (via init code)\n     */\n    function getCodeAddress(bytes memory code) public view returns (address) {\n        return address(\n            uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), address(this), uint256(0), keccak256(code)))))\n        );\n    }\n}\n"
      },
      "src/quark-core/src/QuarkWallet.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\nimport {ECDSA} from \"openzeppelin/utils/cryptography/ECDSA.sol\";\nimport {IERC1271} from \"openzeppelin/interfaces/IERC1271.sol\";\n\nimport {CodeJar} from \"codejar/src/CodeJar.sol\";\n\nimport {QuarkStateManager} from \"quark-core/src/QuarkStateManager.sol\";\nimport {IHasSignerExecutor} from \"quark-core/src/interfaces/IHasSignerExecutor.sol\";\n\n/**\n * @title Quark Wallet Metadata\n * @notice A library of metadata specific to this implementation of the Quark Wallet\n * @author Compound Labs, Inc.\n */\nlibrary QuarkWalletMetadata {\n    /// @notice QuarkWallet contract name\n    string internal constant NAME = \"Quark Wallet\";\n\n    /// @notice QuarkWallet contract major version\n    string internal constant VERSION = \"1\";\n\n    /// @notice The EIP-712 typehash for authorizing an operation for this version of QuarkWallet\n    bytes32 internal constant QUARK_OPERATION_TYPEHASH = keccak256(\n        \"QuarkOperation(uint96 nonce,address scriptAddress,bytes[] scriptSources,bytes scriptCalldata,uint256 expiry)\"\n    );\n\n    /// @notice The EIP-712 typehash for authorizing a MultiQuarkOperation for this version of QuarkWallet\n    bytes32 internal constant MULTI_QUARK_OPERATION_TYPEHASH = keccak256(\"MultiQuarkOperation(bytes32[] opDigests)\");\n\n    /// @notice The EIP-712 typehash for authorizing an EIP-1271 signature for this version of QuarkWallet\n    bytes32 internal constant QUARK_MSG_TYPEHASH = keccak256(\"QuarkMessage(bytes message)\");\n\n    /// @notice The EIP-712 domain typehash for this version of QuarkWallet\n    bytes32 internal constant DOMAIN_TYPEHASH =\n        keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n    /// @notice The EIP-712 domain typehash used for MultiQuarkOperations for this version of QuarkWallet\n    bytes32 internal constant MULTI_QUARK_OPERATION_DOMAIN_TYPEHASH =\n        keccak256(\"EIP712Domain(string name,string version)\");\n}\n\n/**\n * @title Quark Wallet base class\n * @notice A smart wallet that can run transaction scripts\n * @dev An implementor needs only to provide a public signer and executor: these could be constants, immutables, or address getters of any kind\n * @author Compound Labs, Inc.\n */\ncontract QuarkWallet is IERC1271 {\n    error BadSignatory();\n    error EmptyCode();\n    error InvalidEIP1271Signature();\n    error InvalidMultiQuarkOperation();\n    error InvalidSignature();\n    error NoActiveCallback();\n    error SignatureExpired();\n    error Unauthorized();\n\n    /// @notice Enum specifying the method of execution for running a Quark script\n    enum ExecutionType {\n        Signature,\n        Direct\n    }\n\n    /// @notice Event emitted when a Quark script is executed by this Quark wallet\n    event ExecuteQuarkScript(\n        address indexed executor, address indexed scriptAddress, uint96 indexed nonce, ExecutionType executionType\n    );\n\n    /// @notice Address of CodeJar contract used to deploy transaction script source code\n    CodeJar public immutable codeJar;\n\n    /// @notice Address of QuarkStateManager contract that manages nonces and nonce-namespaced transaction script storage\n    QuarkStateManager public immutable stateManager;\n\n    /// @notice Name of contract\n    string public constant NAME = QuarkWalletMetadata.NAME;\n\n    /// @notice The major version of this contract\n    string public constant VERSION = QuarkWalletMetadata.VERSION;\n\n    /// @dev The EIP-712 domain typehash for this wallet\n    bytes32 internal constant DOMAIN_TYPEHASH = QuarkWalletMetadata.DOMAIN_TYPEHASH;\n\n    /// @dev The EIP-712 domain typehash used for MultiQuarkOperations for this wallet\n    bytes32 internal constant MULTI_QUARK_OPERATION_DOMAIN_TYPEHASH =\n        QuarkWalletMetadata.MULTI_QUARK_OPERATION_DOMAIN_TYPEHASH;\n\n    /// @dev The EIP-712 typehash for authorizing an operation for this wallet\n    bytes32 internal constant QUARK_OPERATION_TYPEHASH = QuarkWalletMetadata.QUARK_OPERATION_TYPEHASH;\n\n    /// @dev The EIP-712 typehash for authorizing an operation that is part of a MultiQuarkOperation for this wallet\n    bytes32 internal constant MULTI_QUARK_OPERATION_TYPEHASH = QuarkWalletMetadata.MULTI_QUARK_OPERATION_TYPEHASH;\n\n    /// @dev The EIP-712 typehash for authorizing an EIP-1271 signature for this wallet\n    bytes32 internal constant QUARK_MSG_TYPEHASH = QuarkWalletMetadata.QUARK_MSG_TYPEHASH;\n\n    /// @dev The EIP-712 domain separator for a MultiQuarkOperation\n    /// @dev Note: `chainId` and `verifyingContract` are left out so a single MultiQuarkOperation can be used to\n    ///            execute operations on different chains and wallets.\n    bytes32 internal constant MULTI_QUARK_OPERATION_DOMAIN_SEPARATOR = keccak256(\n        abi.encode(\n            QuarkWalletMetadata.MULTI_QUARK_OPERATION_DOMAIN_TYPEHASH,\n            keccak256(bytes(QuarkWalletMetadata.NAME)),\n            keccak256(bytes(QuarkWalletMetadata.VERSION))\n        )\n    );\n\n    /// @notice Well-known stateManager key for the currently executing script's callback address (if any)\n    bytes32 public constant CALLBACK_KEY = keccak256(\"callback.v1.quark\");\n\n    /// @notice The magic value to return for valid ERC1271 signature\n    bytes4 internal constant EIP_1271_MAGIC_VALUE = 0x1626ba7e;\n\n    /// @notice The structure of a signed operation to execute in the context of this wallet\n    struct QuarkOperation {\n        /// @notice Nonce identifier for the operation\n        uint96 nonce;\n        /// @notice The address of the transaction script to run\n        address scriptAddress;\n        /// @notice Creation codes Quark must ensure are deployed before executing this operation\n        bytes[] scriptSources;\n        /// @notice Encoded function selector + arguments to invoke on the script contract\n        bytes scriptCalldata;\n        /// @notice Expiration time for the signature corresponding to this operation\n        uint256 expiry;\n    }\n\n    /**\n     * @notice Construct a new QuarkWalletImplementation\n     * @param codeJar_ The CodeJar contract used to deploy scripts\n     * @param stateManager_ The QuarkStateManager contract used to write/read nonces and storage for this wallet\n     */\n    constructor(CodeJar codeJar_, QuarkStateManager stateManager_) {\n        codeJar = codeJar_;\n        stateManager = stateManager_;\n    }\n\n    /**\n     * @notice Execute a QuarkOperation via signature\n     * @dev Can only be called with signatures from the wallet's signer\n     * @param op A QuarkOperation struct\n     * @param v EIP-712 signature v value\n     * @param r EIP-712 signature r value\n     * @param s EIP-712 signature s value\n     * @return Return value from the executed operation\n     */\n    function executeQuarkOperation(QuarkOperation calldata op, uint8 v, bytes32 r, bytes32 s)\n        external\n        returns (bytes memory)\n    {\n        bytes32 opDigest = getDigestForQuarkOperation(op);\n\n        return verifySigAndExecuteQuarkOperation(op, opDigest, v, r, s);\n    }\n\n    /**\n     * @notice Execute a QuarkOperation that is part of a MultiQuarkOperation via signature\n     * @dev Can only be called with signatures from the wallet's signer\n     * @param op A QuarkOperation struct\n     * @param opDigests A list of EIP-712 digests for the operations in a MultiQuarkOperation\n     * @param v EIP-712 signature v value\n     * @param r EIP-712 signature r value\n     * @param s EIP-712 signature s value\n     * @return Return value from the executed operation\n     */\n    function executeMultiQuarkOperation(\n        QuarkOperation calldata op,\n        bytes32[] memory opDigests,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public returns (bytes memory) {\n        bytes32 opDigest = getDigestForQuarkOperation(op);\n\n        bool isValidOp = false;\n        for (uint256 i = 0; i < opDigests.length; ++i) {\n            if (opDigest == opDigests[i]) {\n                isValidOp = true;\n                break;\n            }\n        }\n        if (!isValidOp) {\n            revert InvalidMultiQuarkOperation();\n        }\n        bytes32 multiOpDigest = getDigestForMultiQuarkOperation(opDigests);\n\n        return verifySigAndExecuteQuarkOperation(op, multiOpDigest, v, r, s);\n    }\n\n    /**\n     * @notice Verify a signature and execute a QuarkOperation\n     * @param op A QuarkOperation struct\n     * @param digest A EIP-712 digest for either a QuarkOperation or MultiQuarkOperation to verify the signature against\n     * @param v EIP-712 signature v value\n     * @param r EIP-712 signature r value\n     * @param s EIP-712 signature s value\n     * @return Return value from the executed operation\n     */\n    function verifySigAndExecuteQuarkOperation(\n        QuarkOperation calldata op,\n        bytes32 digest,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal returns (bytes memory) {\n        if (block.timestamp >= op.expiry) {\n            revert SignatureExpired();\n        }\n\n        // if the signature check does not revert, the signature is valid\n        checkValidSignatureInternal(IHasSignerExecutor(address(this)).signer(), digest, v, r, s);\n\n        // guarantee every script in scriptSources is deployed\n        for (uint256 i = 0; i < op.scriptSources.length; ++i) {\n            codeJar.saveCode(op.scriptSources[i]);\n        }\n\n        emit ExecuteQuarkScript(msg.sender, op.scriptAddress, op.nonce, ExecutionType.Signature);\n\n        return stateManager.setActiveNonceAndCallback(op.nonce, op.scriptAddress, op.scriptCalldata);\n    }\n\n    /**\n     * @notice Execute a transaction script directly\n     * @dev Can only be called by the wallet's executor\n     * @param nonce Nonce for the operation; must be unused\n     * @param scriptAddress Address for the script to execute\n     * @param scriptCalldata Encoded call to invoke on the script\n     * @param scriptSources Creation codes Quark must ensure are deployed before executing the script\n     * @return Return value from the executed operation\n     */\n    function executeScript(\n        uint96 nonce,\n        address scriptAddress,\n        bytes calldata scriptCalldata,\n        bytes[] calldata scriptSources\n    ) external returns (bytes memory) {\n        // only allow the executor for the wallet to use unsigned execution\n        if (msg.sender != IHasSignerExecutor(address(this)).executor()) {\n            revert Unauthorized();\n        }\n\n        // guarantee every script in scriptSources is deployed\n        for (uint256 i = 0; i < scriptSources.length; ++i) {\n            codeJar.saveCode(scriptSources[i]);\n        }\n\n        emit ExecuteQuarkScript(msg.sender, scriptAddress, nonce, ExecutionType.Direct);\n\n        return stateManager.setActiveNonceAndCallback(nonce, scriptAddress, scriptCalldata);\n    }\n\n    /**\n     * @dev Returns the domain separator for this Quark wallet\n     * @return Domain separator\n     */\n    function getDomainSeparator() internal view returns (bytes32) {\n        return keccak256(\n            abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(NAME)), keccak256(bytes(VERSION)), block.chainid, address(this))\n        );\n    }\n\n    /**\n     * @dev Returns the EIP-712 digest for a QuarkOperation\n     * @param op A QuarkOperation struct\n     * @return EIP-712 digest\n     */\n    function getDigestForQuarkOperation(QuarkOperation calldata op) public view returns (bytes32) {\n        bytes memory encodedScriptSources;\n        for (uint256 i = 0; i < op.scriptSources.length; ++i) {\n            encodedScriptSources = abi.encodePacked(encodedScriptSources, keccak256(op.scriptSources[i]));\n        }\n\n        bytes32 structHash = keccak256(\n            abi.encode(\n                QUARK_OPERATION_TYPEHASH,\n                op.nonce,\n                op.scriptAddress,\n                keccak256(encodedScriptSources),\n                keccak256(op.scriptCalldata),\n                op.expiry\n            )\n        );\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", getDomainSeparator(), structHash));\n    }\n\n    /**\n     * @dev Returns the EIP-712 digest for a MultiQuarkOperation\n     * @param opDigests A list of EIP-712 digests for the operations in a MultiQuarkOperation\n     * @return EIP-712 digest\n     */\n    function getDigestForMultiQuarkOperation(bytes32[] memory opDigests) public pure returns (bytes32) {\n        bytes memory encodedOpDigests;\n        for (uint256 i = 0; i < opDigests.length; ++i) {\n            encodedOpDigests = abi.encodePacked(encodedOpDigests, opDigests[i]);\n        }\n\n        bytes32 structHash = keccak256(abi.encode(MULTI_QUARK_OPERATION_TYPEHASH, keccak256(encodedOpDigests)));\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", MULTI_QUARK_OPERATION_DOMAIN_SEPARATOR, structHash));\n    }\n\n    /**\n     * @dev Returns the EIP-712 digest of a QuarkMessage that can be signed by `signer`\n     * @param message Message that should be hashed\n     * @return Message hash\n     */\n    function getDigestForQuarkMessage(bytes memory message) public view returns (bytes32) {\n        bytes32 quarkMessageHash = keccak256(abi.encode(QUARK_MSG_TYPEHASH, keccak256(message)));\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", getDomainSeparator(), quarkMessageHash));\n    }\n\n    /**\n     * @notice Checks whether an EIP-1271 signature is valid\n     * @dev If the QuarkWallet is owned by an EOA, isValidSignature confirms\n     * that the signature comes from the signer; if the QuarkWallet is owned by\n     * a smart contract, isValidSignature relays the `isValidSignature` to the\n     * smart contract\n     * @param hash Hash of the signed data\n     * @param signature Signature byte array associated with data\n     * @return The ERC-1271 \"magic value\" that indicates the signature is valid\n     */\n    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4) {\n        /*\n         * Code taken directly from OpenZeppelin ECDSA.tryRecover; see:\n         * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/HEAD/contracts/utils/cryptography/ECDSA.sol#L64-L68\n         *\n         * This is effectively an optimized variant of the Reference Implementation; see:\n         * https://eips.ethereum.org/EIPS/eip-1271#reference-implementation\n         */\n        if (signature.length != 65) {\n            revert InvalidSignature();\n        }\n        bytes32 r;\n        bytes32 s;\n        uint8 v;\n        assembly {\n            r := mload(add(signature, 0x20))\n            s := mload(add(signature, 0x40))\n            v := byte(0, mload(add(signature, 0x60)))\n        }\n        // Note: The following logic further encodes the provided `hash` with the wallet's domain\n        // to prevent signature replayability for Quark wallets owned by the same `signer`\n        bytes32 digest = getDigestForQuarkMessage(abi.encode(hash));\n        // If the signature check does not revert, the signature is valid\n        checkValidSignatureInternal(IHasSignerExecutor(address(this)).signer(), digest, v, r, s);\n        return EIP_1271_MAGIC_VALUE;\n    }\n\n    /**\n     * @dev If the QuarkWallet is owned by an EOA, isValidSignature confirms\n     * that the signature comes from the signer; if the QuarkWallet is owned by\n     * a smart contract, isValidSignature relays the `isValidSignature` check\n     * to the smart contract; if the smart contract that owns the wallet has no\n     * code, the signature will be treated as an EIP-712 signature and revert\n     */\n    function checkValidSignatureInternal(address signatory, bytes32 digest, uint8 v, bytes32 r, bytes32 s)\n        internal\n        view\n    {\n        if (signatory.code.length > 0) {\n            bytes memory signature = abi.encodePacked(r, s, v);\n            (bool success, bytes memory data) =\n                signatory.staticcall(abi.encodeWithSelector(EIP_1271_MAGIC_VALUE, digest, signature));\n            if (!success) {\n                revert InvalidEIP1271Signature();\n            }\n            bytes4 returnValue = abi.decode(data, (bytes4));\n            if (returnValue != EIP_1271_MAGIC_VALUE) {\n                revert InvalidEIP1271Signature();\n            }\n        } else {\n            (address recoveredSigner, ECDSA.RecoverError recoverError) = ECDSA.tryRecover(digest, v, r, s);\n            if (recoverError != ECDSA.RecoverError.NoError) {\n                revert InvalidSignature();\n            }\n            if (recoveredSigner != signatory) {\n                revert BadSignatory();\n            }\n        }\n    }\n\n    /**\n     * @notice Execute a QuarkOperation with a lock acquired on nonce-namespaced storage\n     * @dev Can only be called by stateManager during setActiveNonceAndCallback()\n     * @param scriptAddress Address of script to execute\n     * @param scriptCalldata Encoded calldata for the call to execute on the scriptAddress\n     * @return Result of executing the script, encoded as bytes\n     */\n    function executeScriptWithNonceLock(address scriptAddress, bytes memory scriptCalldata)\n        external\n        returns (bytes memory)\n    {\n        require(msg.sender == address(stateManager));\n        if (scriptAddress.code.length == 0) {\n            revert EmptyCode();\n        }\n\n        bool success;\n        uint256 returnSize;\n        uint256 scriptCalldataLen = scriptCalldata.length;\n        assembly {\n            // Note: CALLCODE is used to set the QuarkWallet as the `msg.sender`\n            success :=\n                callcode(gas(), scriptAddress, /* value */ 0, add(scriptCalldata, 0x20), scriptCalldataLen, 0x0, 0)\n            returnSize := returndatasize()\n        }\n\n        bytes memory returnData = new bytes(returnSize);\n        assembly {\n            returndatacopy(add(returnData, 0x20), 0x00, returnSize)\n        }\n\n        if (!success) {\n            assembly {\n                revert(add(returnData, 0x20), returnSize)\n            }\n        }\n\n        return returnData;\n    }\n\n    /**\n     * @notice Fallback function specifically used for scripts that have enabled callbacks\n     * @dev Reverts if callback is not enabled by the script\n     */\n    fallback(bytes calldata data) external payable returns (bytes memory) {\n        address callback = address(uint160(uint256(stateManager.read(CALLBACK_KEY))));\n        if (callback != address(0)) {\n            (bool success, bytes memory result) = callback.delegatecall(data);\n            if (!success) {\n                assembly {\n                    let size := mload(result)\n                    revert(add(result, 0x20), size)\n                }\n            }\n            return result;\n        } else {\n            revert NoActiveCallback();\n        }\n    }\n\n    /// @notice Fallback for receiving native token\n    receive() external payable {}\n}\n"
      },
      "src/quark-core/src/QuarkStateManager.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\nimport {IQuarkWallet} from \"quark-core/src/interfaces/IQuarkWallet.sol\";\n\n/**\n * @title Quark State Manager\n * @notice Contract for managing nonces and storage for Quark wallets, guaranteeing storage isolation across wallets\n *         and Quark operations\n * @author Compound Labs, Inc.\n */\ncontract QuarkStateManager {\n    event ClearNonce(address indexed wallet, uint96 nonce);\n\n    error NoActiveNonce();\n    error NoUnusedNonces();\n    error NonceAlreadySet();\n    error NonceScriptMismatch();\n\n    /// @notice Bit-packed structure of a nonce-script pair\n    struct NonceScript {\n        uint96 nonce;\n        address scriptAddress;\n    }\n\n    /// @notice Bit-packed nonce values\n    mapping(address wallet => mapping(uint256 bucket => uint256 bitset)) public nonces;\n\n    /// @notice Per-wallet-nonce address for preventing replays with changed script address\n    mapping(address wallet => mapping(uint96 nonce => address scriptAddress)) public nonceScriptAddress;\n\n    /// @notice Per-wallet-nonce storage space that can be utilized while a nonce is active\n    mapping(address wallet => mapping(uint96 nonce => mapping(bytes32 key => bytes32 value))) public walletStorage;\n\n    /// @notice Currently active nonce-script pair for a wallet, if any, for which storage is accessible\n    mapping(address wallet => NonceScript) internal activeNonceScript;\n\n    /**\n     * @notice Return whether a nonce has been exhausted; note that if a nonce is not set, that does not mean it has not been used before\n     * @param wallet Address of the wallet owning the nonce\n     * @param nonce Nonce to check\n     * @return Whether the nonce has been exhausted\n     */\n    function isNonceSet(address wallet, uint96 nonce) public view returns (bool) {\n        (uint256 bucket, uint256 mask) = getBucket(nonce);\n        return isNonceSetInternal(wallet, bucket, mask);\n    }\n\n    /// @dev Returns if a given nonce is set for a wallet, using the nonce's bucket and mask\n    function isNonceSetInternal(address wallet, uint256 bucket, uint256 mask) internal view returns (bool) {\n        return (nonces[wallet][bucket] & mask) != 0;\n    }\n\n    /**\n     * @notice Returns the next valid unset nonce for a given wallet\n     * @dev Any unset nonce is valid to use, but using this method\n     * increases the likelihood that the nonce you use will be in a bucket that\n     * has already been written to, which costs less gas\n     * @param wallet Address of the wallet to find the next nonce for\n     * @return The next unused nonce\n     */\n    function nextNonce(address wallet) external view returns (uint96) {\n        // Any bucket larger than `type(uint88).max` will result in unsafe undercast when converting to nonce\n        for (uint256 bucket = 0; bucket <= type(uint88).max; ++bucket) {\n            uint96 bucketValue = uint96(bucket << 8);\n            uint256 bucketNonces = nonces[wallet][bucket];\n            // Move on to the next bucket if all bits in this bucket are already set\n            if (bucketNonces == type(uint256).max) continue;\n            for (uint256 maskOffset = 0; maskOffset < 256; ++maskOffset) {\n                uint256 mask = 1 << maskOffset;\n                if ((bucketNonces & mask) == 0) {\n                    uint96 nonce = uint96(bucketValue + maskOffset);\n                    // The next available nonce should not be reserved for a replayable transaction\n                    if (nonceScriptAddress[wallet][nonce] == address(0)) {\n                        return nonce;\n                    }\n                }\n            }\n        }\n\n        revert NoUnusedNonces();\n    }\n\n    /**\n     * @notice Return the script address associated with the currently active nonce; revert if none\n     * @return Currently active script address\n     */\n    function getActiveScript() external view returns (address) {\n        address scriptAddress = activeNonceScript[msg.sender].scriptAddress;\n        if (scriptAddress == address(0)) {\n            revert NoActiveNonce();\n        }\n        return scriptAddress;\n    }\n\n    /// @dev Locate a nonce at a (bucket, mask) bitset position in the nonces mapping\n    function getBucket(uint96 nonce) internal pure returns (uint256, /* bucket */ uint256 /* mask */ ) {\n        uint256 bucket = nonce >> 8;\n        uint256 setMask = 1 << (nonce & 0xff);\n        return (bucket, setMask);\n    }\n\n    /// @notice Clears (un-sets) the active nonce to allow its reuse; allows a script to be replayed\n    function clearNonce() external {\n        if (activeNonceScript[msg.sender].scriptAddress == address(0)) {\n            revert NoActiveNonce();\n        }\n\n        uint96 nonce = activeNonceScript[msg.sender].nonce;\n        (uint256 bucket, uint256 setMask) = getBucket(nonce);\n        nonces[msg.sender][bucket] &= ~setMask;\n        emit ClearNonce(msg.sender, nonce);\n    }\n\n    /**\n     * @notice Set a given nonce for the calling wallet; effectively cancels any replayable script using that nonce\n     * @param nonce Nonce to set for the calling wallet\n     */\n    function setNonce(uint96 nonce) external {\n        // TODO: should we check whether there exists a nonceScriptAddress?\n        (uint256 bucket, uint256 setMask) = getBucket(nonce);\n        setNonceInternal(bucket, setMask);\n    }\n\n    /// @dev Set a nonce for the msg.sender, using the nonce's bucket and mask\n    function setNonceInternal(uint256 bucket, uint256 setMask) internal {\n        nonces[msg.sender][bucket] |= setMask;\n    }\n\n    /**\n     * @notice Set a wallet nonce as the active nonce and yield control back to the wallet by calling into callback\n     * @param nonce Nonce to activate for the transaction\n     * @param scriptAddress Address of script to invoke with nonce lock\n     * @param scriptCalldata Calldata for script call to invoke with nonce lock\n     * @return Return value from the executed operation\n     * @dev The script is expected to clearNonce() if it wishes to be replayable\n     */\n    function setActiveNonceAndCallback(uint96 nonce, address scriptAddress, bytes calldata scriptCalldata)\n        external\n        returns (bytes memory)\n    {\n        // retrieve the (bucket, mask) pair that addresses the nonce in memory\n        (uint256 bucket, uint256 setMask) = getBucket(nonce);\n\n        // ensure nonce is not already set\n        if (isNonceSetInternal(msg.sender, bucket, setMask)) {\n            revert NonceAlreadySet();\n        }\n\n        address cachedScriptAddress = nonceScriptAddress[msg.sender][nonce];\n        // if the nonce has been used before, check if the script address matches, and revert if not\n        if ((cachedScriptAddress != address(0)) && (cachedScriptAddress != scriptAddress)) {\n            revert NonceScriptMismatch();\n        }\n\n        // spend the nonce; only if the callee chooses to clear it will it get un-set and become replayable\n        setNonceInternal(bucket, setMask);\n\n        // set the nonce-script pair active and yield to the wallet callback\n        NonceScript memory previousNonceScript = activeNonceScript[msg.sender];\n        activeNonceScript[msg.sender] = NonceScript({nonce: nonce, scriptAddress: scriptAddress});\n\n        bytes memory result = IQuarkWallet(msg.sender).executeScriptWithNonceLock(scriptAddress, scriptCalldata);\n\n        // if a nonce was cleared, set the nonceScriptAddress to lock nonce re-use to the same script address\n        if (cachedScriptAddress == address(0) && !isNonceSetInternal(msg.sender, bucket, setMask)) {\n            nonceScriptAddress[msg.sender][nonce] = scriptAddress;\n        }\n\n        // release the nonce when the wallet finishes executing callback\n        activeNonceScript[msg.sender] = previousNonceScript;\n\n        return result;\n    }\n\n    /// @notice Write arbitrary bytes to storage namespaced by the currently active nonce; reverts if no nonce is currently active\n    function write(bytes32 key, bytes32 value) external {\n        if (activeNonceScript[msg.sender].scriptAddress == address(0)) {\n            revert NoActiveNonce();\n        }\n        walletStorage[msg.sender][activeNonceScript[msg.sender].nonce][key] = value;\n    }\n\n    /**\n     * @notice Read from storage namespaced by the currently active nonce; reverts if no nonce is currently active\n     * @return Value at the nonce storage location, as bytes\n     */\n    function read(bytes32 key) external view returns (bytes32) {\n        if (activeNonceScript[msg.sender].scriptAddress == address(0)) {\n            revert NoActiveNonce();\n        }\n        return walletStorage[msg.sender][activeNonceScript[msg.sender].nonce][key];\n    }\n}\n"
      },
      "src/quark-proxy/src/QuarkWalletProxyFactory.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\nimport {QuarkWallet, QuarkWalletMetadata} from \"quark-core/src/QuarkWallet.sol\";\n\nimport {QuarkMinimalProxy} from \"quark-proxy/src/QuarkMinimalProxy.sol\";\n\n/**\n * @title Quark Wallet Proxy Factory\n * @notice A factory for deploying Quark Wallet Proxy instances at deterministic addresses\n * @author Compound Labs, Inc.\n */\ncontract QuarkWalletProxyFactory {\n    event WalletDeploy(address indexed signer, address indexed executor, address walletAddress, bytes32 salt);\n\n    /// @notice Major version of the contract\n    uint256 public constant VERSION = 1;\n\n    /// @notice Default initial salt value\n    bytes32 public constant DEFAULT_SALT = bytes32(0);\n\n    /// @notice The EIP-712 domain separator for a MultiQuarkOperation\n    bytes32 public constant MULTI_QUARK_OPERATION_DOMAIN_SEPARATOR = keccak256(\n        abi.encode(\n            QuarkWalletMetadata.MULTI_QUARK_OPERATION_DOMAIN_TYPEHASH,\n            keccak256(bytes(QuarkWalletMetadata.NAME)),\n            keccak256(bytes(QuarkWalletMetadata.VERSION))\n        )\n    );\n\n    /// @notice Address of QuarkWallet implementation contract\n    address public immutable walletImplementation;\n\n    /// @notice Construct a new QuarkWalletProxyFactory with the provided QuarkWallet implementation address\n    constructor(address walletImplementation_) {\n        walletImplementation = walletImplementation_;\n    }\n\n    /**\n     * @notice Returns the EIP-712 domain separator used for signing operations for the wallet belonging\n     * to the given (signer, executor, salt) triple\n     * @dev Only for use for wallets deployed by this factory, or counterfactual wallets that\n     * will be deployed with this factory; only a wallet with the expected QuarkWalletMetadata\n     * (NAME, VERSION, DOMAIN_TYPEHASH) will work.\n     * @return bytes32 The domain separator for the wallet corresponding to the signer and salt\n     */\n    function DOMAIN_SEPARATOR(address signer, address executor, bytes32 salt) external view returns (bytes32) {\n        return keccak256(\n            abi.encode(\n                QuarkWalletMetadata.DOMAIN_TYPEHASH,\n                keccak256(bytes(QuarkWalletMetadata.NAME)),\n                keccak256(bytes(QuarkWalletMetadata.VERSION)),\n                block.chainid,\n                walletAddressForSalt(signer, executor, salt)\n            )\n        );\n    }\n\n    /**\n     * @notice Create new QuarkWallet for (signer, executor) pair (with default salt value)\n     * @dev Will revert if wallet already exists for signer\n     * @param signer Address to set as the signer of the QuarkWallet\n     * @param executor Address to set as the executor of the QuarkWallet\n     * @return address Address of the newly-created wallet\n     */\n    function create(address signer, address executor) external returns (address payable) {\n        return create(signer, executor, DEFAULT_SALT);\n    }\n\n    /**\n     * @notice Create new QuarkWallet for (signer, executor, salt) triple\n     * @dev Will revert if wallet already exists for (signer, executor, salt) triple\n     * @param signer Address to set as the signer of the QuarkWallet\n     * @param executor Address to set as the executor of the QuarkWallet\n     * @param salt Salt value to use during creation of QuarkWallet\n     * @return address Address of the newly-created wallet\n     */\n    function create(address signer, address executor, bytes32 salt) public returns (address payable) {\n        address payable proxyAddress =\n            payable(address(new QuarkMinimalProxy{salt: salt}(walletImplementation, signer, executor)));\n        emit WalletDeploy(signer, executor, proxyAddress, salt);\n        return proxyAddress;\n    }\n\n    /**\n     * @notice Create a wallet for (signer, executor) pair (and default salt) if it does not exist, then execute operation\n     * @param signer Address to set as the signer of the QuarkWallet\n     * @param executor Address to set as the executor of the QuarkWallet\n     * @param op The QuarkOperation to execute on the wallet\n     * @param v EIP-712 Signature `v` value\n     * @param r EIP-712 Signature `r` value\n     * @param s EIP-712 Signature `s` value\n     * @return bytes Return value of executing the operation\n     */\n    function createAndExecute(\n        address signer,\n        address executor,\n        QuarkWallet.QuarkOperation memory op,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external returns (bytes memory) {\n        return createAndExecute(signer, executor, DEFAULT_SALT, op, v, r, s);\n    }\n\n    /**\n     * @notice Create a wallet for (signer, executor, salt) triple if it does not exist, then execute operation\n     * @param signer Address to set as the signer of the QuarkWallet\n     * @param executor Address to set as the executor of the QuarkWallet\n     * @param salt Salt value of QuarkWallet to create and execute operation with\n     * @param op The QuarkOperation to execute on the wallet\n     * @param v EIP-712 Signature `v` value\n     * @param r EIP-712 Signature `r` value\n     * @param s EIP-712 Signature `s` value\n     * @return bytes Return value of executing the operation\n     */\n    function createAndExecute(\n        address signer,\n        address executor,\n        bytes32 salt,\n        QuarkWallet.QuarkOperation memory op,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public returns (bytes memory) {\n        address payable walletAddress = walletAddressForSalt(signer, executor, salt);\n        if (walletAddress.code.length == 0) {\n            create(signer, executor, salt);\n        }\n\n        return QuarkWallet(walletAddress).executeQuarkOperation(op, v, r, s);\n    }\n\n    /**\n     * @notice Create a wallet for (signer, executor) pair (and default salt) if it does not exist, then execute operation that is part of a MultiQuarkOperation\n     * @param signer Address to set as the signer of the QuarkWallet\n     * @param executor Address to set as the executor of the QuarkWallet\n     * @param op The QuarkOperation to execute on the wallet\n     * @param opDigests A list of EIP-712 digests for the operations in a MultiQuarkOperation\n     * @param v EIP-712 Signature `v` value\n     * @param r EIP-712 Signature `r` value\n     * @param s EIP-712 Signature `s` value\n     * @return bytes Return value of executing the operation\n     */\n    function createAndExecuteMulti(\n        address signer,\n        address executor,\n        QuarkWallet.QuarkOperation calldata op,\n        bytes32[] calldata opDigests,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external returns (bytes memory) {\n        return createAndExecuteMulti(signer, executor, DEFAULT_SALT, op, opDigests, v, r, s);\n    }\n\n    /**\n     * @notice Create a wallet for (signer, executor, salt) triple if it does not exist, then execute operation that is part of a MultiQuarkOperation\n     * @param signer Address to set as the signer of the QuarkWallet\n     * @param executor Address to set as the executor of the QuarkWallet\n     * @param salt Salt value of QuarkWallet to create and execute operation with\n     * @param op The QuarkOperation to execute on the wallet\n     * @param opDigests A list of EIP-712 digests for the operations in a MultiQuarkOperation\n     * @param v EIP-712 Signature `v` value\n     * @param r EIP-712 Signature `r` value\n     * @param s EIP-712 Signature `s` value\n     * @return bytes Return value of executing the operation\n     */\n    function createAndExecuteMulti(\n        address signer,\n        address executor,\n        bytes32 salt,\n        QuarkWallet.QuarkOperation calldata op,\n        bytes32[] calldata opDigests,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public returns (bytes memory) {\n        address payable walletAddress = walletAddressForSalt(signer, executor, salt);\n        if (walletAddress.code.length == 0) {\n            create(signer, executor, salt);\n        }\n\n        return QuarkWallet(walletAddress).executeMultiQuarkOperation(op, opDigests, v, r, s);\n    }\n\n    /**\n     * @notice Derive QuarkWallet address for (signer, executor) pair (and default salt value)\n     * @dev QuarkWallet at returned address may not yet have been created\n     * @param signer Address of the signer for which to derive a QuarkWallet address\n     * @param executor Address of the executor for which to derive a QuarkWallet address\n     * @return address Address of the derived QuarkWallet for (signer, executor) pair\n     */\n    function walletAddressFor(address signer, address executor) external view returns (address payable) {\n        return walletAddressForSalt(signer, executor, DEFAULT_SALT);\n    }\n\n    /**\n     * @notice Derive QuarkWallet address for (signer, executor, salt) triple\n     * @dev QuarkWallet at returned address may not yet have been created\n     * @param signer Address of the signer for which to derive a QuarkWallet address\n     * @param executor Address of the executor for which to derive a QuarkWallet address\n     * @param salt Salt value for which to derive a QuarkWallet address\n     * @return address Address of the derived QuarkWallet for (signer, executor, salt) triple\n     */\n    function walletAddressForSalt(address signer, address executor, bytes32 salt)\n        public\n        view\n        returns (address payable)\n    {\n        return walletAddressForInternal(signer, executor, salt);\n    }\n\n    /// @dev Get the deterministic address of a QuarkWallet for a given (signer, executor, salt) triple\n    function walletAddressForInternal(address signer, address executor, bytes32 salt)\n        internal\n        view\n        returns (address payable)\n    {\n        return payable(\n            address(\n                uint160(\n                    uint256(\n                        keccak256(\n                            abi.encodePacked(\n                                bytes1(0xff),\n                                address(this),\n                                salt,\n                                keccak256(\n                                    abi.encodePacked(\n                                        type(QuarkMinimalProxy).creationCode,\n                                        abi.encode(walletImplementation),\n                                        abi.encode(signer),\n                                        abi.encode(executor)\n                                    )\n                                )\n                            )\n                        )\n                    )\n                )\n            )\n        );\n    }\n}\n"
      },
      "src/quark-core/src/periphery/BatchExecutor.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\nimport {QuarkWallet} from \"quark-core/src/QuarkWallet.sol\";\n\n/**\n * @title Batch Executor for Quark Operations\n * @notice An entry point contract that enables a submitter to submit multiple Quark Operations for different\n *         accounts in a single transaction\n * @author Compound Labs, Inc.\n */\ncontract BatchExecutor {\n    error BatchExecutionError(uint256 opIndex, bytes err);\n\n    /// @notice The parameters used for processing a QuarkOperation\n    struct OperationParams {\n        address account;\n        QuarkWallet.QuarkOperation op;\n        uint8 v;\n        bytes32 r;\n        bytes32 s;\n        uint256 gasLimit;\n    }\n\n    /**\n     * @notice Execute a list of QuarkOperations via signatures\n     * @param ops List of QuarkOperations to execute via signature\n     * @param allowPartialFailures Whether or not to allow partial failures when any of the calls revert\n     */\n    function batchExecuteOperations(OperationParams[] calldata ops, bool allowPartialFailures) external {\n        for (uint256 i = 0; i < ops.length; ++i) {\n            (bool success, bytes memory returnData) = executeOperation(ops[i]);\n            if (!allowPartialFailures && !success) {\n                revert BatchExecutionError(i, returnData);\n            }\n        }\n    }\n\n    /**\n     * @notice Execute a single QuarkOperation via signature\n     * @param op Quark Operation parameters to execute via signature\n     * @return Success and return value from the executed operation\n     */\n    function executeOperation(OperationParams memory op) internal returns (bool, bytes memory) {\n        bytes memory data = abi.encodeWithSelector(QuarkWallet.executeQuarkOperation.selector, op.op, op.v, op.r, op.s);\n        // We purposely ignore success and return values since the BatchExecutor will most likely be called by an EOA\n        // Lower-level call is used to avoid reverting on failure\n        (bool success, bytes memory retData) = op.account.call{gas: op.gasLimit}(data);\n        return (success, retData);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV // Deprecated in v4.8\n    }\n\n    function _throwError(RecoverError error) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert(\"ECDSA: invalid signature\");\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert(\"ECDSA: invalid signature length\");\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert(\"ECDSA: invalid signature 's' value\");\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature` or error string. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            /// @solidity memory-safe-assembly\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength);\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 opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\n        return tryRecover(hash, v, r, s);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     *\n     * _Available since v4.2._\n     */\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n        _throwError(error);\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     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\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);\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);\n        }\n\n        return (signer, RecoverError.NoError);\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) = tryRecover(hash, v, r, s);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n            mstore(0x1c, hash)\n            message := keccak256(0x00, 0x3c)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, \"\\x19\\x01\")\n            mstore(add(ptr, 0x02), domainSeparator)\n            mstore(add(ptr, 0x22), structHash)\n            data := keccak256(ptr, 0x42)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Data with intended validator, created from a\n     * `validator` and `data` according to the version 0 of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n    /**\n     * @dev Should return whether the signature provided is valid for the provided data\n     * @param hash      Hash of the data to be signed\n     * @param signature Signature byte array associated with _data\n     */\n    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n"
      },
      "src/quark-core/src/interfaces/IHasSignerExecutor.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\n/**\n * @title Has Signer and Executor interface\n * @notice A helper interface that represents a shell for a QuarkWallet providing an executor and signer\n * @author Compound Labs, Inc.\n */\ninterface IHasSignerExecutor {\n    function signer() external view returns (address);\n    function executor() external view returns (address);\n}\n"
      },
      "src/quark-core/src/interfaces/IQuarkWallet.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\n/**\n * @title Quark Wallet interface\n * @notice An interface for interacting with Quark Wallets\n * @author Compound Labs, Inc.\n */\ninterface IQuarkWallet {\n    /// @notice The structure of a signed operation to execute in the context of this wallet\n    struct QuarkOperation {\n        /// @notice Nonce identifier for the operation\n        uint96 nonce;\n        /// @notice The address of the transaction script to run\n        address scriptAddress;\n        /// @notice Creation codes Quark must ensure are deployed before executing this operation\n        bytes[] scriptSources;\n        /// @notice Encoded function selector + arguments to invoke on the script contract\n        bytes scriptCalldata;\n        /// @notice Expiration time for the signature corresponding to this operation\n        uint256 expiry;\n    }\n\n    function executeQuarkOperation(QuarkOperation calldata op, uint8 v, bytes32 r, bytes32 s)\n        external\n        returns (bytes memory);\n    function executeMultiQuarkOperation(\n        QuarkOperation calldata op,\n        bytes32[] memory opDigests,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external returns (bytes memory);\n    function executeScript(\n        uint96 nonce,\n        address scriptAddress,\n        bytes calldata scriptCalldata,\n        bytes[] calldata scriptSources\n    ) external returns (bytes memory);\n    function getDigestForQuarkOperation(QuarkOperation calldata op) external view returns (bytes32);\n    function getDigestForMultiQuarkOperation(bytes32[] memory opDigests) external pure returns (bytes32);\n    function getDigestForQuarkMessage(bytes memory message) external view returns (bytes32);\n    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4);\n    function executeScriptWithNonceLock(address scriptAddress, bytes memory scriptCalldata)\n        external\n        returns (bytes memory);\n}\n"
      },
      "src/quark-proxy/src/QuarkMinimalProxy.sol": {
        "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.23;\n\ncontract QuarkMinimalProxy {\n    /// @notice Address of the EOA signer or the EIP-1271 contract that verifies signed operations for this wallet\n    address public immutable signer;\n\n    /// @notice Address of the executor contract, if any, empowered to direct-execute unsigned operations for this wallet\n    address public immutable executor;\n\n    /// @notice Address of the QuarkWallet implementation contract\n    address internal immutable walletImplementation;\n\n    /**\n     * @notice Construct a new QuarkWallet\n     * @param implementation_ Address of QuarkWallet implementation contract\n     * @param signer_ Address allowed to sign QuarkOperations for this wallet\n     * @param executor_ Address allowed to directly execute Quark scripts for this wallet\n     */\n    constructor(address implementation_, address signer_, address executor_) {\n        signer = signer_;\n        executor = executor_;\n        walletImplementation = implementation_;\n    }\n\n    /// @notice Proxy calls to the underlying wallet implementation\n    fallback(bytes calldata /* data */ ) external payable returns (bytes memory) {\n        address walletImplementation_ = walletImplementation;\n        assembly {\n            let calldataLen := calldatasize()\n            calldatacopy(0, 0, calldataLen)\n            let success := delegatecall(gas(), walletImplementation_, 0x00, calldataLen, 0x00, 0)\n            let returnSize := returndatasize()\n            returndatacopy(0, 0, returnSize)\n            if success { return(0, returnSize) }\n\n            revert(0, returnSize)\n        }\n    }\n\n    /// @notice Fallback for receiving native token\n    receive() external payable {}\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/Strings.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\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            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\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 toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(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        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] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\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 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 Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\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 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 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 up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 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 prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / 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 prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\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 works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\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^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice 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        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice 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 + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\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 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\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 + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return 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 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            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "test/=test/",
        "codejar/=src/codejar/",
        "legend-scripts/=src/legend-scripts/",
        "quark-core/=src/quark-core/",
        "quark-core-scripts/=src/quark-core-scripts/",
        "quark-factory/=src/quark-factory/",
        "quark-proxy/=src/quark-proxy/",
        "@uniswap/=lib/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
        "forge-std/=lib/forge-std/src/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "openzeppelin/=lib/openzeppelin-contracts/contracts/",
        "v3-core/=lib/v3-core/",
        "v3-periphery/=lib/v3-periphery/contracts/"
      ],
      "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": {}
    }
  }}