From f5502a5eac4ae1033ba75e51efecce21db380c37 Mon Sep 17 00:00:00 2001 From: kevincheng96 Date: Fri, 27 Sep 2024 14:16:50 -0700 Subject: [PATCH] Switch from v,r,s to bytes for signature --- src/quark-core/src/QuarkWallet.sol | 100 +++--- .../src/periphery/BatchExecutor.sol | 6 +- .../src/QuarkWalletProxyFactory.sol | 44 +-- test/ReplayableTransactions.t.sol | 64 ++-- test/lib/BatchCallback.sol | 12 +- test/lib/EvilReceiver.sol | 81 ----- test/lib/ExecuteOtherOperation.sol | 4 +- test/lib/Noncer.sol | 40 +-- test/lib/SignatureHelper.sol | 35 +- .../ConditionalMulticall.t.sol | 40 +-- test/quark-core-scripts/Ethcall.t.sol | 32 +- test/quark-core-scripts/Multicall.t.sol | 36 +-- test/quark-core-scripts/Paycall.t.sol | 32 +- test/quark-core-scripts/Quotecall.t.sol | 32 +- .../quark-core-scripts/UniswapFlashLoan.t.sol | 20 +- .../UniswapFlashSwapExactOut.t.sol | 12 +- test/quark-core/BatchCallback.t.sol | 6 +- test/quark-core/Callbacks.t.sol | 67 ++-- test/quark-core/EIP1271.t.sol | 8 +- test/quark-core/EIP712.t.sol | 46 +-- test/quark-core/Executor.t.sol | 4 +- test/quark-core/Noncer.t.sol | 98 +++--- test/quark-core/QuarkWallet.t.sol | 298 +++++++++--------- test/quark-core/Reverts.t.sol | 16 +- test/quark-core/isValidSignature.t.sol | 6 +- test/quark-core/periphery/BatchExecutor.t.sol | 60 ++-- test/quark-proxy/QuarkMinimalProxy.t.sol | 4 +- .../quark-proxy/QuarkWalletProxyFactory.t.sol | 46 +-- 28 files changed, 545 insertions(+), 704 deletions(-) delete mode 100644 test/lib/EvilReceiver.sol diff --git a/src/quark-core/src/QuarkWallet.sol b/src/quark-core/src/QuarkWallet.sol index 2f4a83df..db64aa94 100644 --- a/src/quark-core/src/QuarkWallet.sol +++ b/src/quark-core/src/QuarkWallet.sol @@ -171,16 +171,14 @@ contract QuarkWallet is IERC1271 { * @notice Execute a QuarkOperation via signature * @dev Can only be called with signatures from the wallet's signer * @param op A QuarkOperation struct - * @param v EIP-712 signature v value - * @param r EIP-712 signature r value - * @param s EIP-712 signature s value + * @param signature A EIP-712 signature * @return Return value from the executed operation */ - function executeQuarkOperation(QuarkOperation calldata op, uint8 v, bytes32 r, bytes32 s) + function executeQuarkOperation(QuarkOperation calldata op, bytes calldata signature) external returns (bytes memory) { - return executeQuarkOperationWithSubmissionToken(op, op.nonce, v, r, s); + return executeQuarkOperationWithSubmissionToken(op, op.nonce, signature); } /** @@ -188,21 +186,17 @@ contract QuarkWallet is IERC1271 { * @dev Can only be called with signatures from the wallet's signer * @param op A QuarkOperation struct * @param submissionToken The submission token for the replayable quark operation for QuarkNonceManager. This is initially the `op.nonce`, and for replayable operations, it is the next token in the nonce chain. - * @param v EIP-712 signature v value - * @param r EIP-712 signature r value - * @param s EIP-712 signature s value + * @param signature A EIP-712 signature * @return Return value from the executed operation */ function executeQuarkOperationWithSubmissionToken( QuarkOperation calldata op, bytes32 submissionToken, - uint8 v, - bytes32 r, - bytes32 s + bytes calldata signature ) public returns (bytes memory) { bytes32 opDigest = getDigestForQuarkOperation(op); - return verifySigAndExecuteQuarkOperation(op, submissionToken, opDigest, v, r, s); + return verifySigAndExecuteQuarkOperation(op, submissionToken, opDigest, signature); } /** @@ -210,19 +204,15 @@ contract QuarkWallet is IERC1271 { * @dev Can only be called with signatures from the wallet's signer * @param op A QuarkOperation struct * @param opDigests A list of EIP-712 digests for the operations in a MultiQuarkOperation - * @param v EIP-712 signature v value - * @param r EIP-712 signature r value - * @param s EIP-712 signature s value + * @param signature A EIP-712 signature * @return Return value from the executed operation */ function executeMultiQuarkOperation( QuarkOperation calldata op, - bytes32[] memory opDigests, - uint8 v, - bytes32 r, - bytes32 s + bytes32[] calldata opDigests, + bytes calldata signature ) public returns (bytes memory) { - return executeMultiQuarkOperationWithSubmissionToken(op, op.nonce, opDigests, v, r, s); + return executeMultiQuarkOperationWithSubmissionToken(op, op.nonce, opDigests, signature); } /** @@ -231,18 +221,14 @@ contract QuarkWallet is IERC1271 { * @param op A QuarkOperation struct * @param submissionToken The submission token for the replayable quark operation for QuarkNonceManager. This is initially the `op.nonce`, and for replayable operations, it is the next token in the nonce chain. * @param opDigests A list of EIP-712 digests for the operations in a MultiQuarkOperation - * @param v EIP-712 signature v value - * @param r EIP-712 signature r value - * @param s EIP-712 signature s value + * @param signature A EIP-712 signature * @return Return value from the executed operation */ function executeMultiQuarkOperationWithSubmissionToken( QuarkOperation calldata op, bytes32 submissionToken, - bytes32[] memory opDigests, - uint8 v, - bytes32 r, - bytes32 s + bytes32[] calldata opDigests, + bytes calldata signature ) public returns (bytes memory) { bytes32 opDigest = getDigestForQuarkOperation(op); @@ -258,7 +244,7 @@ contract QuarkWallet is IERC1271 { } bytes32 multiOpDigest = getDigestForMultiQuarkOperation(opDigests); - return verifySigAndExecuteQuarkOperation(op, submissionToken, multiOpDigest, v, r, s); + return verifySigAndExecuteQuarkOperation(op, submissionToken, multiOpDigest, signature); } /** @@ -266,25 +252,21 @@ contract QuarkWallet is IERC1271 { * @param op A QuarkOperation struct * @param submissionToken The submission token for the replayable quark operation for QuarkNonceManager. This is initially the `op.nonce`, and for replayable operations, it is the next token in the nonce chain. * @param digest A EIP-712 digest for either a QuarkOperation or MultiQuarkOperation to verify the signature against - * @param v EIP-712 signature v value - * @param r EIP-712 signature r value - * @param s EIP-712 signature s value + * @param signature A EIP-712 signature * @return Return value from the executed operation */ function verifySigAndExecuteQuarkOperation( QuarkOperation calldata op, bytes32 submissionToken, bytes32 digest, - uint8 v, - bytes32 r, - bytes32 s + bytes calldata signature ) internal returns (bytes memory) { if (block.timestamp >= op.expiry) { revert SignatureExpired(); } // if the signature check does not revert, the signature is valid - checkValidSignatureInternal(IHasSignerExecutor(address(this)).signer(), digest, v, r, s); + checkValidSignatureInternal(IHasSignerExecutor(address(this)).signer(), digest, signature); // guarantee every script in scriptSources is deployed for (uint256 i = 0; i < op.scriptSources.length; ++i) { @@ -399,29 +381,11 @@ contract QuarkWallet is IERC1271 { * @return The ERC-1271 "magic value" that indicates the signature is valid */ function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4) { - /* - * Code taken directly from OpenZeppelin ECDSA.tryRecover; see: - * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/HEAD/contracts/utils/cryptography/ECDSA.sol#L64-L68 - * - * This is effectively an optimized variant of the Reference Implementation; see: - * https://eips.ethereum.org/EIPS/eip-1271#reference-implementation - */ - if (signature.length != 65) { - revert InvalidSignature(); - } - bytes32 r; - bytes32 s; - uint8 v; - assembly { - r := mload(add(signature, 0x20)) - s := mload(add(signature, 0x40)) - v := byte(0, mload(add(signature, 0x60))) - } // Note: The following logic further encodes the provided `hash` with the wallet's domain // to prevent signature replayability for Quark wallets owned by the same `signer` bytes32 digest = getDigestForQuarkMessage(abi.encode(hash)); // If the signature check does not revert, the signature is valid - checkValidSignatureInternal(IHasSignerExecutor(address(this)).signer(), digest, v, r, s); + checkValidSignatureInternal(IHasSignerExecutor(address(this)).signer(), digest, signature); return EIP_1271_MAGIC_VALUE; } @@ -432,12 +396,9 @@ contract QuarkWallet is IERC1271 { * to the smart contract; if the smart contract that owns the wallet has no * code, the signature will be treated as an EIP-712 signature and revert */ - function checkValidSignatureInternal(address signatory, bytes32 digest, uint8 v, bytes32 r, bytes32 s) - internal - view - { + function checkValidSignatureInternal(address signatory, bytes32 digest, bytes memory signature) internal view { if (signatory.code.length > 0) { - bytes memory signature = abi.encodePacked(r, s, v); + // For EIP-1271 smart contract signers, the signature can be of any signature scheme (e.g. BLS, Passkey) (bool success, bytes memory data) = signatory.staticcall(abi.encodeWithSelector(EIP_1271_MAGIC_VALUE, digest, signature)); if (!success) { @@ -448,7 +409,26 @@ contract QuarkWallet is IERC1271 { revert InvalidEIP1271Signature(); } } else { - (address recoveredSigner, ECDSA.RecoverError recoverError) = ECDSA.tryRecover(digest, v, r, s); + // For EOA signers, this implementation of the QuarkWallet only supports ECDSA signatures + /* + * Code taken directly from OpenZeppelin ECDSA.tryRecover; see: + * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/HEAD/contracts/utils/cryptography/ECDSA.sol#L64-L68 + * + * This is effectively an optimized variant of the Reference Implementation; see: + * https://eips.ethereum.org/EIPS/eip-1271#reference-implementation + */ + if (signature.length != 65) { + revert InvalidSignature(); + } + bytes32 r; + bytes32 s; + uint8 v; + assembly { + r := mload(add(signature, 0x20)) + s := mload(add(signature, 0x40)) + v := byte(0, mload(add(signature, 0x60))) + } + (address recoveredSigner, ECDSA.RecoverError recoverError) = ECDSA.tryRecover(digest, signature); if (recoverError != ECDSA.RecoverError.NoError) { revert InvalidSignature(); } diff --git a/src/quark-core/src/periphery/BatchExecutor.sol b/src/quark-core/src/periphery/BatchExecutor.sol index 07a5ceb9..9102731d 100644 --- a/src/quark-core/src/periphery/BatchExecutor.sol +++ b/src/quark-core/src/periphery/BatchExecutor.sol @@ -16,9 +16,7 @@ contract BatchExecutor { struct OperationParams { address account; QuarkWallet.QuarkOperation op; - uint8 v; - bytes32 r; - bytes32 s; + bytes signature; uint256 gasLimit; } @@ -42,7 +40,7 @@ contract BatchExecutor { * @return Success and return value from the executed operation */ function executeOperation(OperationParams memory op) internal returns (bool, bytes memory) { - bytes memory data = abi.encodeWithSelector(QuarkWallet.executeQuarkOperation.selector, op.op, op.v, op.r, op.s); + bytes memory data = abi.encodeWithSelector(QuarkWallet.executeQuarkOperation.selector, op.op, op.signature); // We purposely ignore success and return values since the BatchExecutor will most likely be called by an EOA // Lower-level call is used to avoid reverting on failure (bool success, bytes memory retData) = op.account.call{gas: op.gasLimit}(data); diff --git a/src/quark-proxy/src/QuarkWalletProxyFactory.sol b/src/quark-proxy/src/QuarkWalletProxyFactory.sol index 415da743..bb661a8c 100644 --- a/src/quark-proxy/src/QuarkWalletProxyFactory.sol +++ b/src/quark-proxy/src/QuarkWalletProxyFactory.sol @@ -87,20 +87,16 @@ contract QuarkWalletProxyFactory { * @param signer Address to set as the signer of the QuarkWallet * @param executor Address to set as the executor of the QuarkWallet * @param op The QuarkOperation to execute on the wallet - * @param v EIP-712 Signature `v` value - * @param r EIP-712 Signature `r` value - * @param s EIP-712 Signature `s` value + * @param signature A EIP-712 signature * @return bytes Return value of executing the operation */ function createAndExecute( address signer, address executor, - QuarkWallet.QuarkOperation memory op, - uint8 v, - bytes32 r, - bytes32 s + QuarkWallet.QuarkOperation calldata op, + bytes calldata signature ) external returns (bytes memory) { - return createAndExecute(signer, executor, DEFAULT_SALT, op, v, r, s); + return createAndExecute(signer, executor, DEFAULT_SALT, op, signature); } /** @@ -109,26 +105,22 @@ contract QuarkWalletProxyFactory { * @param executor Address to set as the executor of the QuarkWallet * @param salt Salt value of QuarkWallet to create and execute operation with * @param op The QuarkOperation to execute on the wallet - * @param v EIP-712 Signature `v` value - * @param r EIP-712 Signature `r` value - * @param s EIP-712 Signature `s` value + * @param signature A EIP-712 signature * @return bytes Return value of executing the operation */ function createAndExecute( address signer, address executor, bytes32 salt, - QuarkWallet.QuarkOperation memory op, - uint8 v, - bytes32 r, - bytes32 s + QuarkWallet.QuarkOperation calldata op, + bytes calldata signature ) public returns (bytes memory) { address payable walletAddress = walletAddressForSalt(signer, executor, salt); if (walletAddress.code.length == 0) { create(signer, executor, salt); } - return QuarkWallet(walletAddress).executeQuarkOperation(op, v, r, s); + return QuarkWallet(walletAddress).executeQuarkOperation(op, signature); } /** @@ -137,9 +129,7 @@ contract QuarkWalletProxyFactory { * @param executor Address to set as the executor of the QuarkWallet * @param op The QuarkOperation to execute on the wallet * @param opDigests A list of EIP-712 digests for the operations in a MultiQuarkOperation - * @param v EIP-712 Signature `v` value - * @param r EIP-712 Signature `r` value - * @param s EIP-712 Signature `s` value + * @param signature A EIP-712 signature * @return bytes Return value of executing the operation */ function createAndExecuteMulti( @@ -147,11 +137,9 @@ contract QuarkWalletProxyFactory { address executor, QuarkWallet.QuarkOperation calldata op, bytes32[] calldata opDigests, - uint8 v, - bytes32 r, - bytes32 s + bytes calldata signature ) external returns (bytes memory) { - return createAndExecuteMulti(signer, executor, DEFAULT_SALT, op, opDigests, v, r, s); + return createAndExecuteMulti(signer, executor, DEFAULT_SALT, op, opDigests, signature); } /** @@ -161,9 +149,7 @@ contract QuarkWalletProxyFactory { * @param salt Salt value of QuarkWallet to create and execute operation with * @param op The QuarkOperation to execute on the wallet * @param opDigests A list of EIP-712 digests for the operations in a MultiQuarkOperation - * @param v EIP-712 Signature `v` value - * @param r EIP-712 Signature `r` value - * @param s EIP-712 Signature `s` value + * @param signature A EIP-712 signature * @return bytes Return value of executing the operation */ function createAndExecuteMulti( @@ -172,16 +158,14 @@ contract QuarkWalletProxyFactory { bytes32 salt, QuarkWallet.QuarkOperation calldata op, bytes32[] calldata opDigests, - uint8 v, - bytes32 r, - bytes32 s + bytes calldata signature ) public returns (bytes memory) { address payable walletAddress = walletAddressForSalt(signer, executor, salt); if (walletAddress.code.length == 0) { create(signer, executor, salt); } - return QuarkWallet(walletAddress).executeMultiQuarkOperation(op, opDigests, v, r, s); + return QuarkWallet(walletAddress).executeMultiQuarkOperation(op, opDigests, signature); } /** diff --git a/test/ReplayableTransactions.t.sol b/test/ReplayableTransactions.t.sol index 0baca2fe..512a1458 100644 --- a/test/ReplayableTransactions.t.sol +++ b/test/ReplayableTransactions.t.sol @@ -109,13 +109,13 @@ contract ReplayableTransactionsTest is Test { ScriptType.ScriptAddress ); op.expiry = purchaseConfig.swapParams.deadline; - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 0 ether); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op, v1, r1, s1); + aliceWallet.executeQuarkOperation(op, signature1); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), totalAmountToPurchase); } @@ -139,24 +139,24 @@ contract ReplayableTransactionsTest is Test { 1 ); op.expiry = purchaseConfig.swapParams.deadline; - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 0 ether); // gas: meter execute vm.resumeGasMetering(); // 1. Execute recurring purchase for the first time - aliceWallet.executeQuarkOperation(op, v1, r1, s1); + aliceWallet.executeQuarkOperation(op, signature1); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 10 ether); // 2a. Cannot buy again unless time interval has passed vm.expectRevert(RecurringPurchase.PurchaseConditionNotMet.selector); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v1, r1, s1); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature1); // 2b. Execute recurring purchase a second time after warping 1 day vm.warp(block.timestamp + purchaseInterval); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v1, r1, s1); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature1); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 20 ether); } @@ -180,7 +180,7 @@ contract ReplayableTransactionsTest is Test { 2 ); op.expiry = purchaseConfig.swapParams.deadline; - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); QuarkWallet.QuarkOperation memory cancelOp = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, @@ -189,19 +189,19 @@ contract ReplayableTransactionsTest is Test { ScriptType.ScriptAddress ); cancelOp.nonce = op.nonce; - (uint8 v2, bytes32 r2, bytes32 s2) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, cancelOp); + bytes memory cancelSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, cancelOp); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 0 ether); // gas: meter execute vm.resumeGasMetering(); // 1. Execute recurring purchase for the first time - aliceWallet.executeQuarkOperation(op, v1, r1, s1); + aliceWallet.executeQuarkOperation(op, signature1); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 10 ether); // 2. Cancel replayable transaction - aliceWallet.executeQuarkOperationWithSubmissionToken(cancelOp, submissionTokens[1], v2, r2, s2); + aliceWallet.executeQuarkOperationWithSubmissionToken(cancelOp, submissionTokens[1], cancelSignature); // 3. Replayable transaction can no longer be executed vm.warp(block.timestamp + purchaseInterval); @@ -210,14 +210,14 @@ contract ReplayableTransactionsTest is Test { QuarkNonceManager.NonReplayableNonce.selector, address(aliceWallet), op.nonce, submissionTokens[1] ) ); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v1, r1, s1); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature1); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.NonReplayableNonce.selector, address(aliceWallet), op.nonce, submissionTokens[2] ) ); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[2], v1, r1, s1); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[2], signature1); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 10 ether); } @@ -268,21 +268,21 @@ contract ReplayableTransactionsTest is Test { cancelOp.expiry = op2.expiry; cancelOp.nonce = op1.nonce; } - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); - (uint8 v2, bytes32 r2, bytes32 s2) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op2); - (uint8 v3, bytes32 r3, bytes32 s3) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, cancelOp); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); + bytes memory signature2 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op2); + bytes memory signature3 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, cancelOp); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 0 ether); // gas: meter execute vm.resumeGasMetering(); // 1a. Execute recurring purchase order #1 - aliceWallet.executeQuarkOperation(op1, v1, r1, s1); + aliceWallet.executeQuarkOperation(op1, signature1); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 10 ether); // 1b. Execute recurring purchase order #2 - aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[1], v2, r2, s2); + aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[1], signature2); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 15 ether); @@ -290,26 +290,26 @@ contract ReplayableTransactionsTest is Test { vm.warp(block.timestamp + purchaseInterval); // 3a. Execute recurring purchase order #1 - aliceWallet.executeQuarkOperationWithSubmissionToken(op1, submissionTokens[2], v1, r1, s1); + aliceWallet.executeQuarkOperationWithSubmissionToken(op1, submissionTokens[2], signature1); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 25 ether); // 3b. Execute recurring purchase order #2 - aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[3], v2, r2, s2); + aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[3], signature2); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 30 ether); // 4. Cancel replayable transaction - aliceWallet.executeQuarkOperationWithSubmissionToken(cancelOp, submissionTokens[4], v3, r3, s3); + aliceWallet.executeQuarkOperationWithSubmissionToken(cancelOp, submissionTokens[4], signature3); // 5. Warp until next purchase period vm.warp(block.timestamp + purchaseInterval); // 6. Both recurring purchase orders can no longer be executed vm.expectRevert(); - aliceWallet.executeQuarkOperationWithSubmissionToken(op1, submissionTokens[4], v1, r1, s1); + aliceWallet.executeQuarkOperationWithSubmissionToken(op1, submissionTokens[4], signature1); vm.expectRevert(); - aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[5], v2, r2, s2); + aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[5], signature2); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 30 ether); } @@ -333,20 +333,20 @@ contract ReplayableTransactionsTest is Test { 1 ); op.expiry = purchaseConfig.swapParams.deadline; - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 0 ether); // gas: meter execute vm.resumeGasMetering(); // 1. Execute recurring purchase for the first time - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[0], v1, r1, s1); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[0], signature1); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 10 ether); // 2. Cannot buy again unless time interval has passed vm.expectRevert(RecurringPurchase.PurchaseConditionNotMet.selector); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v1, r1, s1); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature1); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 10 ether); } @@ -369,12 +369,12 @@ contract ReplayableTransactionsTest is Test { 0 ); op.expiry = block.timestamp - 1; // Set Quark operation expiry to always expire - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(QuarkWallet.SignatureExpired.selector); - aliceWallet.executeQuarkOperation(op, v1, r1, s1); + aliceWallet.executeQuarkOperation(op, signature1); } function testRevertsForExpiredUniswapParams() public { @@ -395,12 +395,12 @@ contract ReplayableTransactionsTest is Test { ScriptType.ScriptAddress, 0 ); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(bytes("Transaction too old")); - aliceWallet.executeQuarkOperation(op, v1, r1, s1); + aliceWallet.executeQuarkOperation(op, signature1); } function testRevertsForPurchasingOverTheLimit() public { @@ -423,14 +423,14 @@ contract ReplayableTransactionsTest is Test { 1 ); op.expiry = purchaseConfig.swapParams.deadline; - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 0 ether); // gas: meter execute vm.resumeGasMetering(); // 1. Execute recurring purchase - aliceWallet.executeQuarkOperation(op, v1, r1, s1); + aliceWallet.executeQuarkOperation(op, signature1); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 10 ether); @@ -439,7 +439,7 @@ contract ReplayableTransactionsTest is Test { // 3. Purchasing again will go over the `totalAmountToPurchase` cap vm.expectRevert(RecurringPurchase.PurchaseConditionNotMet.selector); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v1, r1, s1); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature1); assertEq(IERC20(WETH).balanceOf(address(aliceWallet)), 10 ether); } diff --git a/test/lib/BatchCallback.sol b/test/lib/BatchCallback.sol index b1491e6a..e577e776 100644 --- a/test/lib/BatchCallback.sol +++ b/test/lib/BatchCallback.sol @@ -8,17 +8,13 @@ contract BatchSend { function submitTwo( QuarkWallet wallet1, QuarkWallet.QuarkOperation memory op1, - uint8 v1, - bytes32 r1, - bytes32 s1, + bytes memory signature1, QuarkWallet wallet2, QuarkWallet.QuarkOperation memory op2, - uint8 v2, - bytes32 r2, - bytes32 s2 + bytes memory signature2 ) public returns (uint256) { - wallet1.executeQuarkOperation(op1, v1, r1, s1); - wallet2.executeQuarkOperation(op2, v2, r2, s2); + wallet1.executeQuarkOperation(op1, signature1); + wallet2.executeQuarkOperation(op2, signature2); return IncrementByCallback(address(wallet1)).number(); } } diff --git a/test/lib/EvilReceiver.sol b/test/lib/EvilReceiver.sol deleted file mode 100644 index 24d4cc1b..00000000 --- a/test/lib/EvilReceiver.sol +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -pragma solidity 0.8.27; - -import "quark-core/src/QuarkWallet.sol"; -import "quark-core/src/QuarkScript.sol"; - -import {TransferActions} from "test/lib/Transfer.sol"; - -contract EvilReceiver { - enum AttackType { - REINVOKE_TRANSFER, - STOLEN_SIGNATURE - } - - struct ReentryAttack { - AttackType attackType; - address destination; - uint256 amount; - uint256 maxCalls; - } - - struct StolenSignature { - QuarkWallet.QuarkOperation op; - uint8 v; - bytes32 r; - bytes32 s; - } - - uint256 public loop = 1; - uint256 public count = 0; - ReentryAttack public attack; - StolenSignature public stolenSignature; - address public targetTokenAddress; - - function setAttack(ReentryAttack calldata t) public { - attack = t; - } - - function stealSignature(StolenSignature calldata t) public { - stolenSignature = t; - } - - function setTargetTokenAddress(address t) public { - targetTokenAddress = t; - } - - function startAttack(bool isERC20, address from, address to, uint256 amount) public { - if (count < attack.maxCalls) { - count++; - if (attack.attackType == AttackType.REINVOKE_TRANSFER) { - // Simply cast the address to Terminal script and call the Transfer function - if (isERC20) { - TransferActions(from).transferERC20Token(targetTokenAddress, to, amount); - } else { - TransferActions(from).transferNativeToken(attack.destination, attack.amount); - } - } - - if (attack.attackType == AttackType.STOLEN_SIGNATURE) { - QuarkWallet(payable(msg.sender)).executeQuarkOperation( - stolenSignature.op, stolenSignature.v, stolenSignature.r, stolenSignature.s - ); - } - } - } - - function tokensReceived( - address, /* operator */ - address from, - address, /* to */ - uint256, /* amount */ - bytes calldata, - bytes calldata - ) external { - startAttack(true, from, attack.destination, attack.amount); - } - - receive() external payable { - startAttack(false, msg.sender, attack.destination, attack.amount); - } -} diff --git a/test/lib/ExecuteOtherOperation.sol b/test/lib/ExecuteOtherOperation.sol index 78def12c..2c510832 100644 --- a/test/lib/ExecuteOtherOperation.sol +++ b/test/lib/ExecuteOtherOperation.sol @@ -5,9 +5,9 @@ import "quark-core/src/QuarkWallet.sol"; import "quark-core/src/QuarkScript.sol"; contract ExecuteOtherOperation is QuarkScript { - function run(QuarkWallet.QuarkOperation memory op, uint8 v, bytes32 r, bytes32 s) external returns (bytes memory) { + function run(QuarkWallet.QuarkOperation memory op, bytes memory signature) external returns (bytes memory) { // XXX: this should just be run(uint256,address,bytes) and use direct execute path allowCallback(); - return QuarkWallet(payable(address(this))).executeQuarkOperation(op, v, r, s); + return QuarkWallet(payable(address(this))).executeQuarkOperation(op, signature); } } diff --git a/test/lib/Noncer.sol b/test/lib/Noncer.sol index fb8c1feb..a4bef900 100644 --- a/test/lib/Noncer.sol +++ b/test/lib/Noncer.sol @@ -10,20 +10,15 @@ contract Stow { function getNestedOperation() public view - returns (QuarkWallet.QuarkOperation memory op, bytes32 submissionToken, uint8 v, bytes32 r, bytes32 s) + returns (QuarkWallet.QuarkOperation memory op, bytes32 submissionToken, bytes memory signature) { - (op, submissionToken, v, r, s) = - abi.decode(nestedOperation, (QuarkWallet.QuarkOperation, bytes32, uint8, bytes32, bytes32)); + (op, submissionToken, signature) = abi.decode(nestedOperation, (QuarkWallet.QuarkOperation, bytes32, bytes)); } - function setNestedOperation( - QuarkWallet.QuarkOperation memory op, - bytes32 submissionToken, - uint8 v, - bytes32 r, - bytes32 s - ) public { - nestedOperation = abi.encode(op, submissionToken, v, r, s); + function setNestedOperation(QuarkWallet.QuarkOperation memory op, bytes32 submissionToken, bytes memory signature) + public + { + nestedOperation = abi.encode(op, submissionToken, signature); } } @@ -41,54 +36,51 @@ contract Noncer is QuarkScript { } // TODO: Test nesting with same nonce - function nestedNonce(QuarkWallet.QuarkOperation memory op, uint8 v, bytes32 r, bytes32 s) + function nestedNonce(QuarkWallet.QuarkOperation memory op, bytes memory signature) public returns (bytes32 pre, bytes32 post, bytes memory result) { pre = getActiveNonce(); - result = QuarkWallet(payable(address(this))).executeQuarkOperation(op, v, r, s); + result = QuarkWallet(payable(address(this))).executeQuarkOperation(op, signature); post = getActiveNonce(); return (pre, post, result); } - function nestedSubmissionToken(QuarkWallet.QuarkOperation memory op, uint8 v, bytes32 r, bytes32 s) + function nestedSubmissionToken(QuarkWallet.QuarkOperation memory op, bytes memory signature) public returns (bytes32 pre, bytes32 post, bytes memory result) { pre = getActiveSubmissionToken(); - result = QuarkWallet(payable(address(this))).executeQuarkOperation(op, v, r, s); + result = QuarkWallet(payable(address(this))).executeQuarkOperation(op, signature); post = getActiveSubmissionToken(); return (pre, post, result); } - function nestedReplayCount(QuarkWallet.QuarkOperation memory op, uint8 v, bytes32 r, bytes32 s) + function nestedReplayCount(QuarkWallet.QuarkOperation memory op, bytes memory signature) public returns (uint256 pre, uint256 post, bytes memory result) { pre = getActiveReplayCount(); - result = QuarkWallet(payable(address(this))).executeQuarkOperation(op, v, r, s); + result = QuarkWallet(payable(address(this))).executeQuarkOperation(op, signature); post = getActiveReplayCount(); return (pre, post, result); } - function postNestRead(QuarkWallet.QuarkOperation memory op, uint8 v, bytes32 r, bytes32 s) - public - returns (uint256) - { - QuarkWallet(payable(address(this))).executeQuarkOperation(op, v, r, s); + function postNestRead(QuarkWallet.QuarkOperation memory op, bytes memory signature) public returns (uint256) { + QuarkWallet(payable(address(this))).executeQuarkOperation(op, signature); return readU256("count"); } function nestedPlay(Stow stow) public returns (uint256) { uint256 n = getActiveReplayCount(); if (n == 0) { - (QuarkWallet.QuarkOperation memory op, bytes32 submissionToken, uint8 v, bytes32 r, bytes32 s) = + (QuarkWallet.QuarkOperation memory op, bytes32 submissionToken, bytes memory signature) = stow.getNestedOperation(); bytes memory result = QuarkWallet(payable(address(this))).executeQuarkOperationWithSubmissionToken( - op, submissionToken, v, r, s + op, submissionToken, signature ); (uint256 y) = abi.decode(result, (uint256)); return y + 10; diff --git a/test/lib/SignatureHelper.sol b/test/lib/SignatureHelper.sol index 070e426e..7a7249cd 100644 --- a/test/lib/SignatureHelper.sol +++ b/test/lib/SignatureHelper.sol @@ -5,13 +5,16 @@ import "forge-std/Test.sol"; import "quark-core/src/QuarkWallet.sol"; contract SignatureHelper is Test { + error InvalidSignatureLength(); + function signOp(uint256 privateKey, QuarkWallet wallet, QuarkWallet.QuarkOperation memory op) external view - returns (uint8, bytes32, bytes32) + returns (bytes memory) { bytes32 digest = opDigest(address(wallet), op); - return vm.sign(privateKey, digest); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + return abi.encodePacked(r, s, v); } /* @@ -20,19 +23,31 @@ contract SignatureHelper is Test { function signOpForAddress(uint256 privateKey, address walletAddress, QuarkWallet.QuarkOperation memory op) external view - returns (uint8, bytes32, bytes32) + returns (bytes memory) { bytes32 digest = opDigest(walletAddress, op); - return vm.sign(privateKey, digest); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + return abi.encodePacked(r, s, v); } - function signMultiOp(uint256 privateKey, bytes32[] memory opDigests) - external - pure - returns (uint8, bytes32, bytes32) - { + function signMultiOp(uint256 privateKey, bytes32[] memory opDigests) external pure returns (bytes memory) { bytes32 digest = multiOpDigest(opDigests); - return vm.sign(privateKey, digest); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + return abi.encodePacked(r, s, v); + } + + function decodeSignature(bytes memory signature) external pure returns (uint8 v, bytes32 r, bytes32 s) { + if (signature.length != 65) { + revert InvalidSignatureLength(); + } + bytes32 r; + bytes32 s; + uint8 v; + assembly { + r := mload(add(signature, 0x20)) + s := mload(add(signature, 0x40)) + v := byte(0, mload(add(signature, 0x60))) + } } function opDigest(address walletAddress, QuarkWallet.QuarkOperation memory op) public view returns (bytes32) { diff --git a/test/quark-core-scripts/ConditionalMulticall.t.sol b/test/quark-core-scripts/ConditionalMulticall.t.sol index 59aa206c..1d9453a9 100644 --- a/test/quark-core-scripts/ConditionalMulticall.t.sol +++ b/test/quark-core-scripts/ConditionalMulticall.t.sol @@ -126,9 +126,9 @@ contract ConditionalMulticallTest is Test { abi.encodeWithSelector(ConditionalMulticall.run.selector, callContracts, callDatas, conditions, checkValues), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); // When reaches here, meaning all checks are passed assertEq(IERC20(USDC).balanceOf(address(wallet)), 1_000_000_000); @@ -172,7 +172,7 @@ contract ConditionalMulticallTest is Test { abi.encodeWithSelector(ConditionalMulticall.run.selector, callContracts, callDatas, conditions, checkValues), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.expectRevert( abi.encodeWithSelector( @@ -184,7 +184,7 @@ contract ConditionalMulticallTest is Test { ) ); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testConditionalRunInvalidInput() public { @@ -209,11 +209,11 @@ contract ConditionalMulticallTest is Test { abi.encodeWithSelector(ConditionalMulticall.run.selector, callContracts, callDatas, conditions, checkValues), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.expectRevert(abi.encodeWithSelector(ConditionalMulticall.InvalidInput.selector)); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testConditionalRunMulticallError() public { @@ -276,7 +276,7 @@ contract ConditionalMulticallTest is Test { abi.encodeWithSelector(ConditionalMulticall.run.selector, callContracts, callDatas, conditions, checkValues), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.expectRevert( abi.encodeWithSelector( ConditionalMulticall.MulticallError.selector, @@ -286,7 +286,7 @@ contract ConditionalMulticallTest is Test { ) ); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testConditionalRunEmptyInputIsValid() public { @@ -305,11 +305,11 @@ contract ConditionalMulticallTest is Test { abi.encodeWithSelector(ConditionalMulticall.run.selector, callContracts, callDatas, conditions, checkValues), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // Empty array is a valid input representing a no-op, and it should not revert vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testConditionalRunOnPeriodicRepay() public { @@ -370,7 +370,7 @@ contract ConditionalMulticallTest is Test { abi.encodeWithSelector(ConditionalMulticall.run.selector, callContracts, callDatas, conditions, checkValues), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // Wallet doesn't have USDC, condition will fail vm.expectRevert( abi.encodeWithSelector( @@ -382,7 +382,7 @@ contract ConditionalMulticallTest is Test { ) ); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); vm.pauseGasMetering(); // Wallet has accrue 400 USDC @@ -395,9 +395,9 @@ contract ConditionalMulticallTest is Test { abi.encodeWithSelector(ConditionalMulticall.run.selector, callContracts, callDatas, conditions, checkValues), ScriptType.ScriptAddress ); - (v, r, s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + (signature) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); vm.pauseGasMetering(); // Wallet has accrued another 400 USDC @@ -408,9 +408,9 @@ contract ConditionalMulticallTest is Test { abi.encodeWithSelector(ConditionalMulticall.run.selector, callContracts, callDatas, conditions, checkValues), ScriptType.ScriptAddress ); - (v, r, s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + (signature) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); vm.pauseGasMetering(); // Wallet has accrued another 400 USDC @@ -421,9 +421,9 @@ contract ConditionalMulticallTest is Test { abi.encodeWithSelector(ConditionalMulticall.run.selector, callContracts, callDatas, conditions, checkValues), ScriptType.ScriptAddress ); - (v, r, s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + (signature) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); vm.pauseGasMetering(); // Wallet no longer borrows from Comet, condition 2 will fail @@ -435,7 +435,7 @@ contract ConditionalMulticallTest is Test { abi.encodeWithSelector(ConditionalMulticall.run.selector, callContracts, callDatas, conditions, checkValues), ScriptType.ScriptAddress ); - (v, r, s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + (signature) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.expectRevert( abi.encodeWithSelector( ConditionalChecker.CheckFailed.selector, @@ -446,7 +446,7 @@ contract ConditionalMulticallTest is Test { ) ); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); // Wallet fully pays off debt assertEq(IComet(comet).borrowBalanceOf(address(wallet)), 0); diff --git a/test/quark-core-scripts/Ethcall.t.sol b/test/quark-core-scripts/Ethcall.t.sol index 53fa6d01..7611aa0c 100644 --- a/test/quark-core-scripts/Ethcall.t.sol +++ b/test/quark-core-scripts/Ethcall.t.sol @@ -67,11 +67,11 @@ contract EthcallTest is Test { ); assertEq(counter.number(), 0); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 1); } @@ -91,11 +91,11 @@ contract EthcallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IComet(comet).balanceOf(address(wallet)), 0); @@ -110,11 +110,11 @@ contract EthcallTest is Test { ), ScriptType.ScriptSource ); - (v, r, s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + (signature) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); // Since there is rouding diff, assert on diff is less than 10 wei assertApproxEqAbs(1000e6, IComet(comet).balanceOf(address(wallet)), 2); @@ -137,11 +137,11 @@ contract EthcallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); // gas: do not meter set-up vm.pauseGasMetering(); @@ -154,11 +154,11 @@ contract EthcallTest is Test { ), ScriptType.ScriptSource ); - (v, r, s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + (signature) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); // gas: do not meter set-up vm.pauseGasMetering(); @@ -171,11 +171,11 @@ contract EthcallTest is Test { ), ScriptType.ScriptSource ); - (v, r, s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + (signature) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(USDC).balanceOf(address(wallet)), 1000e6); } @@ -197,12 +197,12 @@ contract EthcallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert("ERC20: transfer amount exceeds balance"); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testEthcallShouldReturnCallResult() public { @@ -220,11 +220,11 @@ contract EthcallTest is Test { ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory quarkReturn = wallet.executeQuarkOperation(op, v, r, s); + bytes memory quarkReturn = wallet.executeQuarkOperation(op, signature); bytes memory returnData = abi.decode(quarkReturn, (bytes)); assertEq(counter.number(), 4); diff --git a/test/quark-core-scripts/Multicall.t.sol b/test/quark-core-scripts/Multicall.t.sol index 90e21952..2b1abd47 100644 --- a/test/quark-core-scripts/Multicall.t.sol +++ b/test/quark-core-scripts/Multicall.t.sol @@ -112,11 +112,11 @@ contract MulticallTest is Test { abi.encodeWithSelector(Multicall.run.selector, callContracts, callDatas), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 15); } @@ -151,11 +151,11 @@ contract MulticallTest is Test { abi.encodeWithSelector(Multicall.run.selector, callContracts, callDatas), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 15); } @@ -201,11 +201,11 @@ contract MulticallTest is Test { abi.encodeWithSelector(Multicall.run.selector, callContracts, callDatas), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(USDC).balanceOf(address(wallet)), 1000e6); assertEq(IComet(cUSDCv3).collateralBalanceOf(address(wallet), WETH), 100 ether); assertApproxEqAbs(IComet(cUSDCv3).borrowBalanceOf(address(wallet)), 1000e6, 2); @@ -233,12 +233,12 @@ contract MulticallTest is Test { abi.encodeWithSelector(Multicall.run.selector, callContracts, callDatas), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.expectRevert(abi.encodeWithSelector(Multicall.InvalidInput.selector)); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testMulticallError() public { @@ -292,7 +292,7 @@ contract MulticallTest is Test { abi.encodeWithSelector(Multicall.run.selector, callContracts, callDatas), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.expectRevert( @@ -304,7 +304,7 @@ contract MulticallTest is Test { ) ); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testEmptyInputIsValid() public { @@ -321,12 +321,12 @@ contract MulticallTest is Test { abi.encodeWithSelector(Multicall.run.selector, callContracts, callDatas), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); // Empty array is a valid input representing a no-op, and it should not revert - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testMulticallShouldReturnCallResults() public { @@ -360,11 +360,11 @@ contract MulticallTest is Test { abi.encodeWithSelector(Multicall.run.selector, callContracts, callDatas), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory quarkReturn = wallet.executeQuarkOperation(op, v, r, s); + bytes memory quarkReturn = wallet.executeQuarkOperation(op, signature); bytes[] memory returnDatas = abi.decode(quarkReturn, (bytes[])); assertEq(counter.number(), 15); @@ -473,12 +473,12 @@ contract MulticallTest is Test { QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( primary, multicall, abi.encodeWithSelector(Multicall.run.selector, targets, calls), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, primary, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, primary, op); // gas: meter execute vm.resumeGasMetering(); - primary.executeQuarkOperation(op, v, r, s); + primary.executeQuarkOperation(op, signature); // wallet A should still have 0.5 ether... assertEq(IERC20(WETH).balanceOf(address(walletA)), 0.5 ether); // wallet B should have 0 ether... @@ -569,10 +569,10 @@ contract MulticallTest is Test { abi.encodeWithSelector(Multicall.run.selector, callContracts, callDatas), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IComet(cUSDCv3).collateralBalanceOf(address(wallet), WETH), 100 ether); assertEq(IComet(cUSDCv3).borrowBalanceOf(address(wallet)), 10_000e6); assertApproxEqAbs(IComet(cWETHv3).balanceOf(address(subWallet1)), 2 ether, 1); diff --git a/test/quark-core-scripts/Paycall.t.sol b/test/quark-core-scripts/Paycall.t.sol index 2276c4fc..80814d1b 100644 --- a/test/quark-core-scripts/Paycall.t.sol +++ b/test/quark-core-scripts/Paycall.t.sol @@ -169,13 +169,13 @@ contract PaycallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectEmit(true, true, true, false); // We ignore the amount because it will differ based on via-IR emit PayForGas(address(wallet), tx.origin, USDC, 10_658_763); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 15); assertApproxEqAbs(IERC20(USDC).balanceOf(address(wallet)), 989e6, 1e6); @@ -206,13 +206,13 @@ contract PaycallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectEmit(true, true, true, false); // We ignore the amount because it will differ based on via-IR emit PayForGas(address(wallet), tx.origin, USDC, 10_921_630); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertApproxEqAbs(IERC20(USDC).balanceOf(address(wallet)), 979e6, 1e6); assertEq(IERC20(USDC).balanceOf(address(this)), 10e6); @@ -267,13 +267,13 @@ contract PaycallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectEmit(true, true, true, false); // We ignore the amount because it will differ based on via-IR emit PayForGas(address(wallet), tx.origin, USDC, 21_450_507); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertApproxEqAbs(IERC20(USDC).balanceOf(address(wallet)), 978e6, 1e6); assertEq(IComet(cUSDCv3).collateralBalanceOf(address(wallet), WETH), 100 ether); @@ -302,11 +302,11 @@ contract PaycallTest is Test { ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory quarkReturn = wallet.executeQuarkOperation(op, v, r, s); + bytes memory quarkReturn = wallet.executeQuarkOperation(op, signature); bytes memory returnData = abi.decode(quarkReturn, (bytes)); bytes memory returnData2 = abi.decode(returnData, (bytes)); @@ -340,12 +340,12 @@ contract PaycallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); vm.expectEmit(true, true, true, false); // We ignore the amount because it will differ based on via-IR emit PayForGas(address(wallet), tx.origin, USDT, 10_488_771); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(WETH).balanceOf(address(this)), 1 ether); // About $8 in USD fees @@ -378,12 +378,12 @@ contract PaycallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); vm.expectEmit(true, true, true, false); // We ignore the amount because it will differ based on via-IR emit PayForGas(address(wallet), tx.origin, WBTC, 30_228); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(WETH).balanceOf(address(this)), 1 ether); // Fees in WBTC will be around ~ 0.00021 WBTC @@ -416,11 +416,11 @@ contract PaycallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(Paycall.TransactionTooExpensive.selector)); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(USDC).balanceOf(address(wallet)), 1000e6); } @@ -440,12 +440,12 @@ contract PaycallTest is Test { abi.encodeWithSelector(Paycall.run.selector, revertsAddress, "", 20e6), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(Reverts.Whoops.selector)); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(USDC).balanceOf(address(wallet)), 1000e6); } diff --git a/test/quark-core-scripts/Quotecall.t.sol b/test/quark-core-scripts/Quotecall.t.sol index 4f87e0f4..77217f54 100644 --- a/test/quark-core-scripts/Quotecall.t.sol +++ b/test/quark-core-scripts/Quotecall.t.sol @@ -176,13 +176,13 @@ contract QuotecallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectEmit(true, true, true, true); emit PayForGas(address(wallet), tx.origin, USDC, 10e6); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 15); assertEq(IERC20(USDC).balanceOf(address(wallet)), 990e6); @@ -213,13 +213,13 @@ contract QuotecallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectEmit(true, true, true, true); emit PayForGas(address(wallet), tx.origin, USDC, 10e6); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(USDC).balanceOf(address(wallet)), 980e6); assertEq(IERC20(USDC).balanceOf(address(this)), 10e6); @@ -248,11 +248,11 @@ contract QuotecallTest is Test { ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory quarkReturn = wallet.executeQuarkOperation(op, v, r, s); + bytes memory quarkReturn = wallet.executeQuarkOperation(op, signature); bytes memory returnData = abi.decode(quarkReturn, (bytes)); bytes memory returnData2 = abi.decode(returnData, (bytes)); @@ -286,12 +286,12 @@ contract QuotecallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); vm.expectEmit(true, true, true, true); emit PayForGas(address(wallet), tx.origin, USDT, 10e6); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(WETH).balanceOf(address(this)), 1 ether); // About $8 in USD fees @@ -324,12 +324,12 @@ contract QuotecallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); vm.expectEmit(true, true, true, true); emit PayForGas(address(wallet), tx.origin, WBTC, 30e3); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(WETH).balanceOf(address(this)), 1 ether); assertEq(IERC20(WBTC).balanceOf(address(wallet)), 99_970_000); @@ -361,11 +361,11 @@ contract QuotecallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(Quotecall.QuoteToleranceExceeded.selector)); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(USDC).balanceOf(address(wallet)), 1000e6); } @@ -396,11 +396,11 @@ contract QuotecallTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(Quotecall.QuoteToleranceExceeded.selector)); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(USDC).balanceOf(address(wallet)), 1000e6); } @@ -420,12 +420,12 @@ contract QuotecallTest is Test { abi.encodeWithSelector(Quotecall.run.selector, revertsAddress, "", 8e6), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(Reverts.Whoops.selector)); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(IERC20(USDC).balanceOf(address(wallet)), 1000e6); } diff --git a/test/quark-core-scripts/UniswapFlashLoan.t.sol b/test/quark-core-scripts/UniswapFlashLoan.t.sol index 11de89c4..dfaeef1b 100644 --- a/test/quark-core-scripts/UniswapFlashLoan.t.sol +++ b/test/quark-core-scripts/UniswapFlashLoan.t.sol @@ -179,9 +179,9 @@ contract UniswapFlashLoanTest is Test { ), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); // Verify that user now has no WETH collateral on Comet, but only LINK assertEq(IComet(comet).collateralBalanceOf(address(wallet), WETH), 0); @@ -216,10 +216,10 @@ contract UniswapFlashLoanTest is Test { ), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.expectRevert(abi.encodeWithSelector(UniswapFlashLoan.InvalidCaller.selector)); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testRevertsForInsufficientFundsToRepayFlashLoan() public { @@ -245,10 +245,10 @@ contract UniswapFlashLoanTest is Test { abi.encodeWithSelector(UniswapFlashLoan.run.selector, payload), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.expectRevert("ERC20: transfer amount exceeds balance"); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testTokensOrderInvariant() public { @@ -276,8 +276,8 @@ contract UniswapFlashLoanTest is Test { ), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); - wallet.executeQuarkOperation(op, v, r, s); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + wallet.executeQuarkOperation(op, signature1); // Lose 1 USDC to flash loan fee assertEq(IERC20(USDC).balanceOf(address(wallet)), 9999e6); @@ -304,9 +304,9 @@ contract UniswapFlashLoanTest is Test { ), ScriptType.ScriptAddress ); - (uint8 v2, bytes32 r2, bytes32 s2) = new SignatureHelper().signOp(alicePrivateKey, wallet, op2); + bytes memory signature2 = new SignatureHelper().signOp(alicePrivateKey, wallet, op2); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op2, v2, r2, s2); + wallet.executeQuarkOperation(op2, signature2); // Lose 1 USDC to flash loan fee assertEq(IERC20(USDC).balanceOf(address(wallet)), 9998e6); diff --git a/test/quark-core-scripts/UniswapFlashSwapExactOut.t.sol b/test/quark-core-scripts/UniswapFlashSwapExactOut.t.sol index f19d7a93..3d10482e 100644 --- a/test/quark-core-scripts/UniswapFlashSwapExactOut.t.sol +++ b/test/quark-core-scripts/UniswapFlashSwapExactOut.t.sol @@ -110,9 +110,9 @@ contract UniswapFlashSwapExactOutTest is Test { abi.encodeWithSelector(UniswapFlashSwapExactOut.run.selector, payload), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); // Verify that user is now supplying 10 + 1 WETH assertEq(IComet(comet).collateralBalanceOf(address(wallet), WETH), 11 ether); @@ -145,10 +145,10 @@ contract UniswapFlashSwapExactOutTest is Test { ), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.expectRevert(abi.encodeWithSelector(UniswapFlashSwapExactOut.InvalidCaller.selector)); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testNotEnoughToPayFlashSwap() public { @@ -189,10 +189,10 @@ contract UniswapFlashSwapExactOutTest is Test { abi.encodeWithSelector(UniswapFlashSwapExactOut.run.selector, payload), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); vm.expectRevert("ERC20: transfer amount exceeds balance"); vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testRevertsIfCalledDirectly() public { diff --git a/test/quark-core/BatchCallback.t.sol b/test/quark-core/BatchCallback.t.sol index ab49410a..54f65c53 100644 --- a/test/quark-core/BatchCallback.t.sol +++ b/test/quark-core/BatchCallback.t.sol @@ -77,7 +77,7 @@ contract BatchCallbackTest is Test { QuarkWallet.QuarkOperation memory op1 = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, incrementByCallbackScript, abi.encodeWithSignature("run()"), ScriptType.ScriptSource ); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); bytes memory callIncrementScript = new YulHelper().getCode("BatchCallback.sol/CallIncrement.json"); QuarkWallet.QuarkOperation memory op2 = new QuarkOperationHelper().newBasicOpWithCalldata( @@ -86,11 +86,11 @@ contract BatchCallbackTest is Test { abi.encodeWithSignature("run(address)", address(aliceWallet)), ScriptType.ScriptSource ); - (uint8 v2, bytes32 r2, bytes32 s2) = new SignatureHelper().signOp(bobPrivateKey, bobWallet, op2); + bytes memory signature2 = new SignatureHelper().signOp(bobPrivateKey, bobWallet, op2); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(QuarkWallet.NoActiveCallback.selector)); - batchSend.submitTwo(aliceWallet, op1, v1, r1, s1, bobWallet, op2, v2, r2, s2); + batchSend.submitTwo(aliceWallet, op1, signature1, bobWallet, op2, signature2); } } diff --git a/test/quark-core/Callbacks.t.sol b/test/quark-core/Callbacks.t.sol index 9f664378..1bcdc270 100644 --- a/test/quark-core/Callbacks.t.sol +++ b/test/quark-core/Callbacks.t.sol @@ -72,11 +72,11 @@ contract CallbacksTest is Test { ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 11); } @@ -97,11 +97,11 @@ contract CallbacksTest is Test { ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 11); assertEq(address(counter).balance, 500 wei); @@ -122,22 +122,22 @@ contract CallbacksTest is Test { ScriptType.ScriptAddress ); - (uint8 v_, bytes32 r_, bytes32 s_) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); + bytes memory nestedOpSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); QuarkWallet.QuarkOperation memory parentOp = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, executeOtherScript, - abi.encodeWithSelector(ExecuteOtherOperation.run.selector, nestedOp, v_, r_, s_), + abi.encodeWithSelector(ExecuteOtherOperation.run.selector, nestedOp, nestedOpSignature), ScriptType.ScriptAddress ); parentOp.nonce = new QuarkOperationHelper().incrementNonce(nestedOp.nonce); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, parentOp); + bytes memory parentOpSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, parentOp); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(parentOp, v, r, s); + aliceWallet.executeQuarkOperation(parentOp, parentOpSignature); assertEq(counter.number(), 11); } @@ -153,22 +153,22 @@ contract CallbacksTest is Test { aliceWallet, getCallbackDetails, abi.encodeWithSignature("getCallbackAddress()"), ScriptType.ScriptAddress ); - (uint8 v_, bytes32 r_, bytes32 s_) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); + bytes memory nestedOpSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); QuarkWallet.QuarkOperation memory parentOp = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, executeOtherScript, - abi.encodeWithSelector(ExecuteOtherOperation.run.selector, nestedOp, v_, r_, s_), + abi.encodeWithSelector(ExecuteOtherOperation.run.selector, nestedOp, nestedOpSignature), ScriptType.ScriptAddress ); parentOp.nonce = new QuarkOperationHelper().incrementNonce(nestedOp.nonce); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, parentOp); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, parentOp); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(parentOp, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(parentOp, signature); // We decode twice because the result is encoded twice due to the nested operation address innerCallbackAddress = abi.decode(abi.decode(result, (bytes)), (address)); @@ -189,22 +189,22 @@ contract CallbacksTest is Test { aliceWallet, counterScript, abi.encodeWithSignature("run(address)", counter), ScriptType.ScriptAddress ); - (uint8 v_, bytes32 r_, bytes32 s_) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); + bytes memory nestedOpSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); QuarkWallet.QuarkOperation memory parentOp = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, executeOtherScript, - abi.encodeWithSelector(ExecuteOtherOperation.run.selector, nestedOp, v_, r_, s_), + abi.encodeWithSelector(ExecuteOtherOperation.run.selector, nestedOp, nestedOpSignature), ScriptType.ScriptAddress ); parentOp.nonce = new QuarkOperationHelper().incrementNonce(nestedOp.nonce); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, parentOp); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, parentOp); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(parentOp, v, r, s); + aliceWallet.executeQuarkOperation(parentOp, signature); assertEq(counter.number(), 2); } @@ -217,16 +217,16 @@ contract CallbacksTest is Test { .newReplayableOpWithCalldata( aliceWallet, allowCallbacks, abi.encodeWithSignature("run()"), ScriptType.ScriptSource, 1 ); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op1, v1, r1, s1); + bytes memory result = aliceWallet.executeQuarkOperation(op1, signature1); uint256 res = abi.decode(result, (uint256)); assertEq(res, 202); // Can run again - result = aliceWallet.executeQuarkOperationWithSubmissionToken(op1, submissionTokens[1], v1, r1, s1); + result = aliceWallet.executeQuarkOperationWithSubmissionToken(op1, submissionTokens[1], signature1); res = abi.decode(result, (uint256)); assertEq(res, 204); } @@ -239,12 +239,12 @@ contract CallbacksTest is Test { (QuarkWallet.QuarkOperation memory op1,) = new QuarkOperationHelper().newReplayableOpWithCalldata( aliceWallet, allowCallbacks, abi.encodeWithSignature("runWithoutAllow()"), ScriptType.ScriptSource, 1 ); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(QuarkWallet.NoActiveCallback.selector)); - aliceWallet.executeQuarkOperation(op1, v1, r1, s1); + aliceWallet.executeQuarkOperation(op1, signature1); } function testWithClearedCallback() public { @@ -255,12 +255,12 @@ contract CallbacksTest is Test { (QuarkWallet.QuarkOperation memory op1,) = new QuarkOperationHelper().newReplayableOpWithCalldata( aliceWallet, allowCallbacks, abi.encodeWithSignature("runAllowThenClear()"), ScriptType.ScriptSource, 1 ); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(QuarkWallet.NoActiveCallback.selector)); - aliceWallet.executeQuarkOperation(op1, v1, r1, s1); + aliceWallet.executeQuarkOperation(op1, signature1); } function testRevertsOnCallbackWhenNoActiveCallback() public { @@ -279,12 +279,12 @@ contract CallbacksTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(QuarkWallet.NoActiveCallback.selector)); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); } /* ===== callback reentrancy tests ===== */ @@ -342,13 +342,13 @@ contract CallbacksTest is Test { ), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); deal(address(aliceWallet), 1000 wei); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); assertEq(callbackCallerAddress.balance, 1000 wei); } @@ -371,14 +371,14 @@ contract CallbacksTest is Test { ), ScriptType.ScriptAddress ); - (uint8 bad_v, bytes32 bad_r, bytes32 bad_s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, badOp); + bytes memory badOpSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, badOp); deal(address(aliceWallet), 1000 wei); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(); // attacker tried to call back into the script with a changed fee - aliceWallet.executeQuarkOperation(badOp, bad_v, bad_r, bad_s); + aliceWallet.executeQuarkOperation(badOp, badOpSignature); // gas: do not meter set-up vm.pauseGasMetering(); @@ -394,12 +394,11 @@ contract CallbacksTest is Test { ), ScriptType.ScriptAddress ); - (uint8 behaved_v, bytes32 behaved_r, bytes32 behaved_s) = - new SignatureHelper().signOp(alicePrivateKey, aliceWallet, behavedOp); + bytes memory behavedSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, behavedOp); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(behavedOp, behaved_v, behaved_r, behaved_s); + aliceWallet.executeQuarkOperation(behavedOp, behavedSignature); // the well-behaved callback caller gets the correct fee assertEq(callbackCallerAddress.balance, 500 wei); } @@ -425,13 +424,13 @@ contract CallbacksTest is Test { ), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); deal(address(aliceWallet), 2 ether); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); // Note: If this was exploitable, the callback caller would have 2 ether assertEq(callbackCallerAddress.balance, 1 ether); } diff --git a/test/quark-core/EIP1271.t.sol b/test/quark-core/EIP1271.t.sol index 2f3cbe79..0ac7ec02 100644 --- a/test/quark-core/EIP1271.t.sol +++ b/test/quark-core/EIP1271.t.sol @@ -63,12 +63,12 @@ contract EIP1271Test is Test { // signature from alice; doesn't matter because the EIP1271Signer will approve anything QuarkWallet.QuarkOperation memory op = incrementCounterOperation(aliceWallet); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - contractWallet.executeQuarkOperation(op, v, r, s); + contractWallet.executeQuarkOperation(op, signature); // counter has incremented assertEq(counter.number(), 3); } @@ -83,13 +83,13 @@ contract EIP1271Test is Test { // signature from alice; doesn't matter because the EIP1271Signer will reject anything QuarkWallet.QuarkOperation memory op = incrementCounterOperation(aliceWallet); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(QuarkWallet.InvalidEIP1271Signature.selector); - contractWallet.executeQuarkOperation(op, v, r, s); + contractWallet.executeQuarkOperation(op, signature); // counter has not incremented assertEq(counter.number(), 0); diff --git a/test/quark-core/EIP712.t.sol b/test/quark-core/EIP712.t.sol index 002c49c3..7df07a22 100644 --- a/test/quark-core/EIP712.t.sol +++ b/test/quark-core/EIP712.t.sol @@ -63,11 +63,11 @@ contract EIP712Test is Test { assertEq(counter.number(), 0); QuarkWallet.QuarkOperation memory op = incrementCounterOperation(wallet); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); // counter has incremented assertEq(counter.number(), 3); @@ -82,7 +82,7 @@ contract EIP712Test is Test { assertEq(counter.number(), 0); QuarkWallet.QuarkOperation memory op = incrementCounterOperation(wallet); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // bad actor modifies script source to selfdestruct the wallet op.scriptSources = new bytes[](1); @@ -93,7 +93,7 @@ contract EIP712Test is Test { // submitter calls executeQuarkOperation with the signed op, but they manipulate the code vm.expectRevert(QuarkWallet.BadSignatory.selector); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); // counter is unchanged assertEq(counter.number(), 0); @@ -173,7 +173,7 @@ contract EIP712Test is Test { assertEq(counter.number(), 0); QuarkWallet.QuarkOperation memory op = incrementCounterOperation(wallet); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // submitter calls executeQuarkOperation with the signed op, but they manipulate the calldata op.scriptCalldata = abi.encodeWithSignature("decrementCounter(address)", counter); @@ -181,7 +181,7 @@ contract EIP712Test is Test { // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); // counter is unchanged assertEq(counter.number(), 0); @@ -196,7 +196,7 @@ contract EIP712Test is Test { assertEq(counter.number(), 0); QuarkWallet.QuarkOperation memory op = incrementCounterOperation(wallet); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // submitter calls executeQuarkOperation with the signed op, but they manipulate the expiry op.expiry += 1; @@ -204,7 +204,7 @@ contract EIP712Test is Test { // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); // counter is unchanged assertEq(counter.number(), 0); @@ -219,12 +219,12 @@ contract EIP712Test is Test { assertEq(counter.number(), 0); QuarkWallet.QuarkOperation memory op = incrementCounterOperation(wallet); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 3); assertEq(nonceManager.submissions(address(wallet), op.nonce), bytes32(type(uint256).max)); @@ -233,7 +233,7 @@ contract EIP712Test is Test { vm.expectRevert( abi.encodeWithSelector(QuarkNonceManager.NonReplayableNonce.selector, address(wallet), op.nonce, op.nonce) ); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); } function testRevertsForExpiredSignature() public { @@ -242,7 +242,7 @@ contract EIP712Test is Test { assertEq(counter.number(), 0); QuarkWallet.QuarkOperation memory op = incrementCounterOperation(wallet); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // the expiry block arrives vm.warp(op.expiry); @@ -252,7 +252,7 @@ contract EIP712Test is Test { // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 0); assertEq(nonceManager.submissions(address(wallet), op.nonce), bytes32(uint256(0))); @@ -264,17 +264,19 @@ contract EIP712Test is Test { assertEq(counter.number(), 0); QuarkWallet.QuarkOperation memory op = incrementCounterOperation(wallet); - (uint8 v, bytes32 r, /* bytes32 s */ ) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + (uint8 v, bytes32 r, /* bytes32 s */ ) = new SignatureHelper().decodeSignature(signature); // 1 greater than the max value of s bytes32 invalidS = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A1; + bytes memory invalidSignature = abi.encodePacked(r, invalidS, v); // submitter calls executeQuarkOperation with invalid `s` value vm.expectRevert(QuarkWallet.InvalidSignature.selector); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, invalidS); + wallet.executeQuarkOperation(op, invalidSignature); assertEq(counter.number(), 0); assertEq(nonceManager.submissions(address(wallet), op.nonce), bytes32(uint256(0))); @@ -298,7 +300,7 @@ contract EIP712Test is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, wallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, wallet, op); // submitter alters the requirements bytes32[] memory badRequirements = new bytes32[](1); @@ -313,7 +315,7 @@ contract EIP712Test is Test { // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(op, v, r, s); + wallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 0); assertEq(nonceManager.submissions(address(wallet), op.nonce), bytes32(uint256(0))); @@ -329,7 +331,7 @@ contract EIP712Test is Test { address incrementerAddress = codeJar.saveCode(incrementer); QuarkWallet.QuarkOperation memory firstOp = incrementCounterOperation(wallet); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, wallet, firstOp); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, wallet, firstOp); bytes32[] memory requirements = new bytes32[](1); requirements[0] = firstOp.nonce; @@ -345,20 +347,20 @@ contract EIP712Test is Test { dependentOp.nonce = new QuarkOperationHelper().incrementNonce(firstOp.nonce); - (uint8 v2, bytes32 r2, bytes32 s2) = new SignatureHelper().signOp(alicePrivateKey, wallet, dependentOp); + bytes memory signature2 = new SignatureHelper().signOp(alicePrivateKey, wallet, dependentOp); // attempting to execute the second operation first reverts vm.expectRevert(abi.encodeWithSelector(ExecuteWithRequirements.RequirementNotMet.selector, firstOp.nonce)); // gas: meter execute vm.resumeGasMetering(); - wallet.executeQuarkOperation(dependentOp, v2, r2, s2); + wallet.executeQuarkOperation(dependentOp, signature2); // but once the first operation is executed... - wallet.executeQuarkOperation(firstOp, v1, r1, s1); + wallet.executeQuarkOperation(firstOp, signature1); assertEq(counter.number(), 3); // the second can be executed - wallet.executeQuarkOperation(dependentOp, v2, r2, s2); + wallet.executeQuarkOperation(dependentOp, signature2); // and its effect can be observed assertEq(counter.number(), 6); } diff --git a/test/quark-core/Executor.t.sol b/test/quark-core/Executor.t.sol index 04af7a32..c7af90de 100644 --- a/test/quark-core/Executor.t.sol +++ b/test/quark-core/Executor.t.sol @@ -108,11 +108,11 @@ contract ExecutorTest is Test { ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 3); } } diff --git a/test/quark-core/Noncer.t.sol b/test/quark-core/Noncer.t.sol index a75236a8..7c41dd4b 100644 --- a/test/quark-core/Noncer.t.sol +++ b/test/quark-core/Noncer.t.sol @@ -75,11 +75,11 @@ contract NoncerTest is Test { QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature("checkNonce()"), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (bytes32 nonceResult) = abi.decode(result, (bytes32)); assertEq(nonceResult, op.nonce); @@ -92,11 +92,11 @@ contract NoncerTest is Test { QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature("checkSubmissionToken()"), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (bytes32 submissionTokenResult) = abi.decode(result, (bytes32)); assertEq(submissionTokenResult, op.nonce); @@ -110,11 +110,11 @@ contract NoncerTest is Test { QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature("checkReplayCount()"), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (uint256 replayCount) = abi.decode(result, (uint256)); assertEq(replayCount, 0); @@ -132,26 +132,21 @@ contract NoncerTest is Test { aliceWallet, noncerScript, abi.encodeWithSignature("checkNonce()"), ScriptType.ScriptSource ); nestedOp.nonce = bytes32(uint256(keccak256(abi.encodePacked(block.timestamp))) - 2); // Don't overlap on nonces - (uint8 nestedV, bytes32 nestedR, bytes32 nestedS) = - new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); + bytes memory nestedOpSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature( - "nestedNonce((bytes32,bool,address,bytes[],bytes,uint256),uint8,bytes32,bytes32)", - nestedOp, - nestedV, - nestedR, - nestedS + "nestedNonce((bytes32,bool,address,bytes[],bytes,uint256),bytes)", nestedOp, nestedOpSignature ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (bytes32 pre, bytes32 post, bytes memory innerResult) = abi.decode(result, (bytes32, bytes32, bytes)); assertEq(pre, op.nonce); @@ -168,26 +163,21 @@ contract NoncerTest is Test { aliceWallet, noncerScript, abi.encodeWithSignature("checkSubmissionToken()"), ScriptType.ScriptSource ); nestedOp.nonce = bytes32(uint256(keccak256(abi.encodePacked(block.timestamp))) - 2); // Don't overlap on nonces - (uint8 nestedV, bytes32 nestedR, bytes32 nestedS) = - new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); + bytes memory nestedOpSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature( - "nestedSubmissionToken((bytes32,bool,address,bytes[],bytes,uint256),uint8,bytes32,bytes32)", - nestedOp, - nestedV, - nestedR, - nestedS + "nestedSubmissionToken((bytes32,bool,address,bytes[],bytes,uint256),bytes)", nestedOp, nestedOpSignature ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (bytes32 pre, bytes32 post, bytes memory innerResult) = abi.decode(result, (bytes32, bytes32, bytes)); assertEq(pre, op.nonce); @@ -207,13 +197,13 @@ contract NoncerTest is Test { .newReplayableOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature("nestedPlay(address)", stow), ScriptType.ScriptSource, 1 ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); - stow.setNestedOperation(op, submissionTokens[1], v, r, s); + stow.setNestedOperation(op, submissionTokens[1], signature); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (uint256 y) = abi.decode(result, (uint256)); assertEq(y, 61); @@ -227,26 +217,21 @@ contract NoncerTest is Test { aliceWallet, noncerScript, abi.encodeWithSignature("checkReplayCount()"), ScriptType.ScriptSource ); nestedOp.nonce = bytes32(uint256(keccak256(abi.encodePacked(block.timestamp))) - 2); // Don't overlap on nonces - (uint8 nestedV, bytes32 nestedR, bytes32 nestedS) = - new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); + bytes memory nestedOpSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature( - "nestedReplayCount((bytes32,bool,address,bytes[],bytes,uint256),uint8,bytes32,bytes32)", - nestedOp, - nestedV, - nestedR, - nestedS + "nestedReplayCount((bytes32,bool,address,bytes[],bytes,uint256),bytes)", nestedOp, nestedOpSignature ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (uint256 pre, uint256 post, bytes memory innerResult) = abi.decode(result, (uint256, uint256, bytes)); assertEq(pre, 0); @@ -264,26 +249,21 @@ contract NoncerTest is Test { aliceWallet, maxCounter, abi.encodeWithSignature("run(address)", address(counter)), ScriptType.ScriptSource ); nestedOp.nonce = bytes32(uint256(keccak256(abi.encodePacked(block.timestamp))) - 2); // Don't overlap on nonces - (uint8 nestedV, bytes32 nestedR, bytes32 nestedS) = - new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); + bytes memory nestedOpSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, nestedOp); QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature( - "postNestRead((bytes32,bool,address,bytes[],bytes,uint256),uint8,bytes32,bytes32)", - nestedOp, - nestedV, - nestedR, - nestedS + "postNestRead((bytes32,bool,address,bytes[],bytes,uint256),bytes)", nestedOp, nestedOpSignature ), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); uint256 value = abi.decode(result, (uint256)); assertEq(value, 0); @@ -310,16 +290,16 @@ contract NoncerTest is Test { .newReplayableOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature("checkNonce()"), ScriptType.ScriptSource, 1 ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (bytes32 nonceResult) = abi.decode(result, (bytes32)); assertEq(nonceResult, op.nonce); - result = aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v, r, s); + result = aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature); (nonceResult) = abi.decode(result, (bytes32)); assertEq(nonceResult, op.nonce); @@ -333,16 +313,16 @@ contract NoncerTest is Test { .newReplayableOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature("checkSubmissionToken()"), ScriptType.ScriptSource, 1 ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (bytes32 submissionTokenResult) = abi.decode(result, (bytes32)); assertEq(submissionTokenResult, submissionTokens[0]); - result = aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v, r, s); + result = aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature); (submissionTokenResult) = abi.decode(result, (bytes32)); assertEq(submissionTokenResult, submissionTokens[1]); @@ -356,21 +336,21 @@ contract NoncerTest is Test { .newReplayableOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature("checkReplayCount()"), ScriptType.ScriptSource, 2 ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (uint256 replayCount) = abi.decode(result, (uint256)); assertEq(replayCount, 0); - result = aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v, r, s); + result = aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature); (replayCount) = abi.decode(result, (uint256)); assertEq(replayCount, 1); - result = aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[2], v, r, s); + result = aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[2], signature); (replayCount) = abi.decode(result, (uint256)); assertEq(replayCount, 2); @@ -385,7 +365,7 @@ contract NoncerTest is Test { .newReplayableOpWithCalldata( aliceWallet, noncerScript, abi.encodeWithSignature("checkReplayCount()"), ScriptType.ScriptSource, 2 ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); QuarkWallet.QuarkOperation memory checkReplayCountOp = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, @@ -394,18 +374,18 @@ contract NoncerTest is Test { ScriptType.ScriptSource, op.nonce ); - (uint8 checkReplayCountOpV, bytes32 checkReplayCountOpR, bytes32 checkReplayCountOpS) = + bytes memory checkReplayCountSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, checkReplayCountOp); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (uint256 replayCount) = abi.decode(result, (uint256)); assertEq(replayCount, 0); result = aliceWallet.executeQuarkOperationWithSubmissionToken( - checkReplayCountOp, submissionTokens[1], checkReplayCountOpV, checkReplayCountOpR, checkReplayCountOpS + checkReplayCountOp, submissionTokens[1], checkReplayCountSignature ); (replayCount) = abi.decode(result, (uint256)); diff --git a/test/quark-core/QuarkWallet.t.sol b/test/quark-core/QuarkWallet.t.sol index ea2ff5d9..ab64179e 100644 --- a/test/quark-core/QuarkWallet.t.sol +++ b/test/quark-core/QuarkWallet.t.sol @@ -108,11 +108,11 @@ contract QuarkWalletTest is Test { QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, getMessageDetails, abi.encodeWithSignature("getMsgDetails()"), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory result = aliceWallet.executeQuarkOperation(op, signature); (address msgSender, address addressThis, uint256 msgValue) = abi.decode(result, (address, address, uint256)); assertEq(msgSender, address(this), "Message sender should be address(this)"); @@ -152,14 +152,12 @@ contract QuarkWalletTest is Test { QuarkWallet.QuarkOperation memory opWithScriptAddress = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, getMessageDetails, abi.encodeWithSignature("getMsgDetails()"), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = - new SignatureHelper().signOp(alicePrivateKey, aliceWallet, opWithScriptAddress); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, opWithScriptAddress); QuarkWallet.QuarkOperation memory opWithScriptSource = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, getMessageDetails, abi.encodeWithSignature("getMsgDetails()"), ScriptType.ScriptSource ); opWithScriptSource.nonce = new QuarkOperationHelper().incrementNonce(opWithScriptSource.nonce); - (uint8 v2, bytes32 r2, bytes32 s2) = - new SignatureHelper().signOp(alicePrivateKey, aliceWallet, opWithScriptSource); + bytes memory signature2 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, opWithScriptSource); address scriptAddress = opWithScriptAddress.scriptAddress; // gas: meter execute @@ -173,7 +171,7 @@ contract QuarkWalletTest is Test { false, ExecutionType.Signature ); - aliceWallet.executeQuarkOperation(opWithScriptAddress, v, r, s); + aliceWallet.executeQuarkOperation(opWithScriptAddress, signature1); vm.expectEmit(true, true, true, true); emit QuarkExecution( @@ -184,7 +182,7 @@ contract QuarkWalletTest is Test { false, ExecutionType.Signature ); - aliceWallet.executeQuarkOperation(opWithScriptSource, v2, r2, s2); + aliceWallet.executeQuarkOperation(opWithScriptSource, signature2); } function testEmitsEventsInReplayableQuarkOperation() public { @@ -196,8 +194,7 @@ contract QuarkWalletTest is Test { aliceWallet, getMessageDetails, abi.encodeWithSignature("getMsgDetails()"), ScriptType.ScriptAddress, 2 ); address scriptAddress = opWithScriptAddress.scriptAddress; - (uint8 v, bytes32 r, bytes32 s) = - new SignatureHelper().signOp(alicePrivateKey, aliceWallet, opWithScriptAddress); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, opWithScriptAddress); // gas: meter execute vm.resumeGasMetering(); @@ -210,21 +207,21 @@ contract QuarkWalletTest is Test { true, ExecutionType.Signature ); - aliceWallet.executeQuarkOperation(opWithScriptAddress, v, r, s); + aliceWallet.executeQuarkOperation(opWithScriptAddress, signature); // second execution vm.expectEmit(true, true, true, true); emit QuarkExecution( address(this), scriptAddress, opWithScriptAddress.nonce, submissionTokens[1], true, ExecutionType.Signature ); - aliceWallet.executeQuarkOperationWithSubmissionToken(opWithScriptAddress, submissionTokens[1], v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(opWithScriptAddress, submissionTokens[1], signature); // third execution vm.expectEmit(true, true, true, true); emit QuarkExecution( address(this), scriptAddress, opWithScriptAddress.nonce, submissionTokens[2], true, ExecutionType.Signature ); - aliceWallet.executeQuarkOperationWithSubmissionToken(opWithScriptAddress, submissionTokens[2], v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(opWithScriptAddress, submissionTokens[2], signature); } function testEmitsEventsInDirectExecute() public { @@ -291,7 +288,7 @@ contract QuarkWalletTest is Test { QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, getMessageDetails, abi.encodeWithSignature("getMsgDetails()"), ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); @@ -300,31 +297,31 @@ contract QuarkWalletTest is Test { vm.expectRevert( abi.encodeWithSelector(QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op.nonce, bytes32(0)) ); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, bytes32(0), v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, bytes32(0), signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op.nonce, bytes32(uint256(1)) ) ); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, bytes32(uint256(1)), v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, bytes32(uint256(1)), signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op.nonce, EXHAUSTED_TOKEN ) ); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, EXHAUSTED_TOKEN, v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, EXHAUSTED_TOKEN, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op.nonce, bytes32(uint256(op.nonce) + 1) ) ); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, bytes32(uint256(op.nonce) + 1), v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, bytes32(uint256(op.nonce) + 1), signature); // Run script - aliceWallet.executeQuarkOperationWithSubmissionToken(op, op.nonce, v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, op.nonce, signature); // Check it is no longer runnable vm.expectRevert( @@ -332,7 +329,7 @@ contract QuarkWalletTest is Test { QuarkNonceManager.NonReplayableNonce.selector, address(aliceWallet), op.nonce, op.nonce ) ); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, op.nonce, v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, op.nonce, signature); } function testDisallowAllNullScriptAddress() public { @@ -347,14 +344,14 @@ contract QuarkWalletTest is Test { scriptCalldata: bytes(""), expiry: block.timestamp + 1000 }); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); // operation containing no script will revert vm.expectRevert(abi.encodeWithSelector(QuarkWallet.EmptyCode.selector)); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); // direct execution of the null script will revert vm.pauseGasMetering(); @@ -379,14 +376,14 @@ contract QuarkWalletTest is Test { scriptCalldata: bytes(""), expiry: block.timestamp + 1000 }); - (uint8 v2, bytes32 r2, bytes32 s2) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op2); + bytes memory signature2 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op2); // gas: meter execute vm.resumeGasMetering(); // operation on empty script will revert vm.expectRevert(abi.encodeWithSelector(QuarkWallet.EmptyCode.selector)); - aliceWallet.executeQuarkOperation(op2, v2, r2, s2); + aliceWallet.executeQuarkOperation(op2, signature2); // direct execution of empty script will revert vm.pauseGasMetering(); @@ -412,13 +409,13 @@ contract QuarkWalletTest is Test { scriptCalldata: bytes("feefee"), expiry: block.timestamp + 1000 }); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(QuarkWallet.EmptyCode.selector)); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); } /* ===== storage tests ===== */ @@ -439,7 +436,7 @@ contract QuarkWalletTest is Test { ScriptType.ScriptAddress, 4 ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); assertEq( vm.load(address(aliceWallet), keccak256(abi.encodePacked(op.nonce, keccak256("count")))), @@ -448,21 +445,21 @@ contract QuarkWalletTest is Test { vm.resumeGasMetering(); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[0], v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[0], signature); assertEq( vm.load(address(aliceWallet), keccak256(abi.encodePacked(op.nonce, keccak256("count")))), bytes32(uint256(1)) ); assertEq(counter.number(), 1); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature); assertEq( vm.load(address(aliceWallet), keccak256(abi.encodePacked(op.nonce, keccak256("count")))), bytes32(uint256(2)) ); assertEq(counter.number(), 2); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[2], v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[2], signature); assertEq( vm.load(address(aliceWallet), keccak256(abi.encodePacked(op.nonce, keccak256("count")))), bytes32(uint256(3)) @@ -470,7 +467,7 @@ contract QuarkWalletTest is Test { assertEq(counter.number(), 3); vm.expectRevert(abi.encodeWithSelector(MaxCounterScript.EnoughAlready.selector)); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[3], v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[3], signature); assertEq( vm.load(address(aliceWallet), keccak256(abi.encodePacked(op.nonce, keccak256("count")))), bytes32(uint256(3)) @@ -494,7 +491,7 @@ contract QuarkWalletTest is Test { ScriptType.ScriptAddress, 1 ); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); address incrementerAddress = codeJar.saveCode(incrementer); @@ -506,38 +503,38 @@ contract QuarkWalletTest is Test { scriptCalldata: abi.encodeWithSignature("incrementCounter2(address)", address(counter)), expiry: block.timestamp + 1000 }); - (uint8 v2, bytes32 r2, bytes32 s2) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op2); + bytes memory signature2 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op2); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op1, v1, r1, s1); + aliceWallet.executeQuarkOperation(op1, signature1); // incrementer increments the counter thrice assertEq(counter.number(), 3); // when executing a replayable operation, you can change the call - aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[1], v2, r2, s2); + aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[1], signature2); // incrementer increments the counter frice assertEq(counter.number(), 7); // but now both operations are exhausted vm.expectRevert( abi.encodeWithSelector(QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op1.nonce, op1.nonce) ); - aliceWallet.executeQuarkOperation(op1, v1, r1, s1); + aliceWallet.executeQuarkOperation(op1, signature1); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op1.nonce, submissionTokens[1] ) ); - aliceWallet.executeQuarkOperationWithSubmissionToken(op1, submissionTokens[1], v1, r1, s1); + aliceWallet.executeQuarkOperationWithSubmissionToken(op1, submissionTokens[1], signature1); vm.expectRevert( abi.encodeWithSelector(QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op1.nonce, op2.nonce) ); - aliceWallet.executeQuarkOperation(op2, v2, r2, s2); + aliceWallet.executeQuarkOperation(op2, signature2); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op1.nonce, submissionTokens[1] ) ); - aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[1], v2, r2, s2); + aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[1], signature2); } function testAllowsForReusedNonceWithChangedScript() public { @@ -555,7 +552,7 @@ contract QuarkWalletTest is Test { ScriptType.ScriptAddress, 1 ); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); + bytes memory signature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op1); QuarkWallet.QuarkOperation memory op2 = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, @@ -564,15 +561,15 @@ contract QuarkWalletTest is Test { ScriptType.ScriptAddress ); op2.nonce = op1.nonce; - (uint8 v2, bytes32 r2, bytes32 s2) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op2); + bytes memory signature2 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op2); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op1, v1, r1, s1); + aliceWallet.executeQuarkOperation(op1, signature1); // incrementer increments the counter thrice assertEq(counter.number(), 3); // when reusing the nonce but changing the script, allow - aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[1], v2, r2, s2); + aliceWallet.executeQuarkOperationWithSubmissionToken(op2, submissionTokens[1], signature2); // updated with larger incrementer script assertEq(counter.number(), 9); } @@ -590,29 +587,26 @@ contract QuarkWalletTest is Test { ScriptType.ScriptAddress, 1 ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 3); // cannot replay the same operation directly... vm.expectRevert( abi.encodeWithSelector(QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op.nonce, op.nonce) ); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 3); // can cancel the replayable nonce... vm.pauseGasMetering(); QuarkWallet.QuarkOperation memory cancelOtherOp = new QuarkOperationHelper().cancelReplayableByNop(aliceWallet, op); - (uint8 cancelV, bytes32 cancelR, bytes32 cancelS) = - new SignatureHelper().signOp(alicePrivateKey, aliceWallet, cancelOtherOp); + bytes memory cancelSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, cancelOtherOp); vm.resumeGasMetering(); - aliceWallet.executeQuarkOperationWithSubmissionToken( - cancelOtherOp, submissionTokens[1], cancelV, cancelR, cancelS - ); + aliceWallet.executeQuarkOperationWithSubmissionToken(cancelOtherOp, submissionTokens[1], cancelSignature); // and now you can no longer replay vm.expectRevert( @@ -620,7 +614,7 @@ contract QuarkWalletTest is Test { QuarkNonceManager.NonReplayableNonce.selector, address(aliceWallet), op.nonce, submissionTokens[1] ) ); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature); // Ensure exhausted assertEq(nonceManager.submissions(address(aliceWallet), op.nonce), bytes32(type(uint256).max)); @@ -639,28 +633,27 @@ contract QuarkWalletTest is Test { ScriptType.ScriptAddress, 1 ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 3); // cannot replay the same operation directly... vm.expectRevert( abi.encodeWithSelector(QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op.nonce, op.nonce) ); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 3); // can cancel the replayable nonce... vm.pauseGasMetering(); QuarkWallet.QuarkOperation memory cancelOp = new QuarkOperationHelper().cancelReplayableByNewOp(aliceWallet, op); - (uint8 cancelV, bytes32 cancelR, bytes32 cancelS) = - new SignatureHelper().signOp(alicePrivateKey, aliceWallet, cancelOp); + bytes memory cancelSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, cancelOp); vm.resumeGasMetering(); vm.expectEmit(true, true, true, true); emit QuarkNonceManager.NonceSubmitted(address(aliceWallet), op.nonce, bytes32(type(uint256).max)); - aliceWallet.executeQuarkOperationWithSubmissionToken(cancelOp, submissionTokens[1], cancelV, cancelR, cancelS); + aliceWallet.executeQuarkOperationWithSubmissionToken(cancelOp, submissionTokens[1], cancelSignature); // and now you can no longer replay vm.expectRevert( @@ -668,7 +661,7 @@ contract QuarkWalletTest is Test { QuarkNonceManager.NonReplayableNonce.selector, address(aliceWallet), op.nonce, submissionTokens[1] ) ); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature); // Ensure exhausted assertEq(nonceManager.submissions(address(aliceWallet), op.nonce), bytes32(type(uint256).max)); @@ -725,14 +718,14 @@ contract QuarkWalletTest is Test { QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, ethcall, ethcallCalldata, ScriptType.ScriptSource ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); assertEq(counter.number(), 0); assertEq(nonceManager.submissions(address(aliceWalletExecutable), nonce), bytes32(uint256(0))); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 3); assertEq(nonceManager.submissions(address(aliceWalletExecutable), nonce), bytes32(type(uint256).max)); @@ -844,16 +837,16 @@ contract QuarkWalletTest is Test { bytes32[] memory opDigests = new bytes32[](2); opDigests[0] = op1Digest; opDigests[1] = op2Digest; - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); + bytes memory signature = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); // call once vm.resumeGasMetering(); - aliceWallet.executeMultiQuarkOperation(op1, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperation(op1, opDigests, signature); assertEq(counter.number(), 3); // call a second time - aliceWallet.executeMultiQuarkOperation(op2, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperation(op2, opDigests, signature); assertEq(counter.number(), 6); } @@ -885,12 +878,12 @@ contract QuarkWalletTest is Test { bytes32[] memory opDigests = new bytes32[](1); opDigests[0] = op1Digest; - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); + bytes memory signature = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); // call with operation that is not part of opDigests vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(QuarkWallet.InvalidMultiQuarkOperation.selector)); - aliceWallet.executeMultiQuarkOperation(op2, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperation(op2, opDigests, signature); assertEq(counter.number(), 0); } @@ -924,11 +917,11 @@ contract QuarkWalletTest is Test { bytes32[] memory opDigests = new bytes32[](2); opDigests[0] = op1Digest; opDigests[1] = op2Digest; - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); + bytes memory signature = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); // call once vm.resumeGasMetering(); - aliceWallet.executeMultiQuarkOperation(op1, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperation(op1, opDigests, signature); assertEq(counter.number(), 3); @@ -938,7 +931,7 @@ contract QuarkWalletTest is Test { QuarkNonceManager.NonReplayableNonce.selector, address(aliceWallet), op1.nonce, op1.nonce ) ); - aliceWallet.executeMultiQuarkOperation(op1, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperation(op1, opDigests, signature); assertEq(counter.number(), 3); } @@ -974,29 +967,29 @@ contract QuarkWalletTest is Test { bytes32[] memory opDigests = new bytes32[](2); opDigests[0] = op1Digest; opDigests[1] = op2Digest; - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); + bytes memory signature = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); vm.resumeGasMetering(); // call op1, first assertEq(nonceManager.submissions(address(aliceWallet), op1.nonce), bytes32(0)); - aliceWallet.executeMultiQuarkOperation(op1, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperation(op1, opDigests, signature); assertEq(counter.number(), 3); assertEq(nonceManager.submissions(address(aliceWallet), op1.nonce), op1.nonce); // call op2, first assertEq(nonceManager.submissions(address(aliceWallet), op2.nonce), bytes32(0)); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[0], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[0], opDigests, signature); assertEq(counter.number(), 7); assertEq(nonceManager.submissions(address(aliceWallet), op2.nonce), op2.nonce); // call op1, second - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[1], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[1], opDigests, signature); assertEq(counter.number(), 10); assertEq(nonceManager.submissions(address(aliceWallet), op1.nonce), submissionTokens1[1]); // call op1, third - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[2], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[2], opDigests, signature); assertEq(counter.number(), 13); // test all tokens do not replay now for op1 @@ -1005,32 +998,32 @@ contract QuarkWalletTest is Test { QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op1.nonce, EXHAUSTED_TOKEN ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, EXHAUSTED_TOKEN, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, EXHAUSTED_TOKEN, opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op1.nonce, submissionTokens1[0] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[0], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[0], opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op1.nonce, submissionTokens1[1] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[1], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[1], opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op1.nonce, submissionTokens1[2] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[2], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[2], opDigests, signature); // call op2, second - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, signature); assertEq(counter.number(), 17); // call op2, third - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[2], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[2], opDigests, signature); assertEq(counter.number(), 21); // test all tokens do not replay now for op2 @@ -1039,25 +1032,25 @@ contract QuarkWalletTest is Test { QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, EXHAUSTED_TOKEN ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, EXHAUSTED_TOKEN, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, EXHAUSTED_TOKEN, opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens2[0] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[0], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[0], opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens2[1] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens2[2] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[2], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[2], opDigests, signature); } function testHalfReplayableMultiQuarkOperation() public { @@ -1089,19 +1082,19 @@ contract QuarkWalletTest is Test { bytes32[] memory opDigests = new bytes32[](2); opDigests[0] = op1Digest; opDigests[1] = op2Digest; - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); + bytes memory signature = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); vm.resumeGasMetering(); // call op1 assertEq(nonceManager.submissions(address(aliceWallet), op1.nonce), bytes32(0)); - aliceWallet.executeMultiQuarkOperation(op1, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperation(op1, opDigests, signature); assertEq(counter.number(), 3); assertEq(nonceManager.submissions(address(aliceWallet), op1.nonce), EXHAUSTED_TOKEN); // call op2, first assertEq(nonceManager.submissions(address(aliceWallet), op2.nonce), bytes32(0)); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[0], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[0], opDigests, signature); assertEq(counter.number(), 7); assertEq(nonceManager.submissions(address(aliceWallet), op2.nonce), op2.nonce); @@ -1111,18 +1104,18 @@ contract QuarkWalletTest is Test { QuarkNonceManager.NonReplayableNonce.selector, aliceWallet, op1.nonce, EXHAUSTED_TOKEN ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, EXHAUSTED_TOKEN, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, EXHAUSTED_TOKEN, opDigests, signature); vm.expectRevert( abi.encodeWithSelector(QuarkNonceManager.NonReplayableNonce.selector, aliceWallet, op1.nonce, op1.nonce) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, op1.nonce, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, op1.nonce, opDigests, signature); // call op2, second - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, signature); assertEq(counter.number(), 11); // call op2, third - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[2], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[2], opDigests, signature); assertEq(counter.number(), 15); // test all tokens do not replay now for op2 @@ -1131,25 +1124,25 @@ contract QuarkWalletTest is Test { QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, EXHAUSTED_TOKEN ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, EXHAUSTED_TOKEN, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, EXHAUSTED_TOKEN, opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens2[0] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[0], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[0], opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens2[1] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens2[2] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[2], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[2], opDigests, signature); } function testReplayableMultiQuarkOperationWithSharedNonce() public { @@ -1183,13 +1176,13 @@ contract QuarkWalletTest is Test { bytes32[] memory opDigests = new bytes32[](2); opDigests[0] = op1Digest; opDigests[1] = op2Digest; - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); + bytes memory signature = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); vm.resumeGasMetering(); // call op1, first assertEq(nonceManager.submissions(address(aliceWallet), op1.nonce), bytes32(0)); - aliceWallet.executeMultiQuarkOperation(op1, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperation(op1, opDigests, signature); assertEq(counter.number(), 3); assertEq(nonceManager.submissions(address(aliceWallet), op1.nonce), op1.nonce); @@ -1199,22 +1192,22 @@ contract QuarkWalletTest is Test { QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens2[0] ) ); - aliceWallet.executeMultiQuarkOperation(op2, opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperation(op2, opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens2[0] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[0], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[0], opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens1[0] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[0], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[0], opDigests, signature); // now submit op2 with submissionTokens[1] - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, signature); assertEq(counter.number(), 7); // ensure neither can be called with submissionTokens[1] now @@ -1223,16 +1216,16 @@ contract QuarkWalletTest is Test { QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens2[1] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[1], opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens1[1] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[1], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[1], opDigests, signature); // call op1, third - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[2], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[2], opDigests, signature); assertEq(counter.number(), 10); // ensure neither can be called with submissionTokens[2] now @@ -1241,13 +1234,13 @@ contract QuarkWalletTest is Test { QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens2[2] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[2], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op2, submissionTokens2[2], opDigests, signature); vm.expectRevert( abi.encodeWithSelector( QuarkNonceManager.InvalidSubmissionToken.selector, aliceWallet, op2.nonce, submissionTokens1[2] ) ); - aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[2], opDigests, v, r, s); + aliceWallet.executeMultiQuarkOperationWithSubmissionToken(op1, submissionTokens1[2], opDigests, signature); } /* ===== basic operation tests ===== */ @@ -1265,13 +1258,13 @@ contract QuarkWalletTest is Test { .newReplayableOpWithCalldata( aliceWallet, maxCounterScript, abi.encodeCall(MaxCounterScript.run, (counter)), ScriptType.ScriptAddress, 4 ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // call once vm.resumeGasMetering(); vm.expectEmit(true, true, true, true); emit MaxCounterScript.Count(1); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); // gas: do not meter walletStorage vm.pauseGasMetering(); @@ -1286,7 +1279,7 @@ contract QuarkWalletTest is Test { vm.resumeGasMetering(); vm.expectEmit(true, true, true, true); emit MaxCounterScript.Count(2); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[1], signature); // gas: do not meter walletStorage vm.pauseGasMetering(); @@ -1301,7 +1294,7 @@ contract QuarkWalletTest is Test { vm.resumeGasMetering(); vm.expectEmit(true, true, true, true); emit MaxCounterScript.Count(3); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[2], v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[2], signature); // gas: do not meter walletStorage vm.pauseGasMetering(); @@ -1315,7 +1308,7 @@ contract QuarkWalletTest is Test { // revert because max has been hit vm.expectRevert(abi.encodeWithSelector(MaxCounterScript.EnoughAlready.selector)); vm.resumeGasMetering(); - aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[3], v, r, s); + aliceWallet.executeQuarkOperationWithSubmissionToken(op, submissionTokens[3], signature); // gas: do not meter walletStorage vm.pauseGasMetering(); @@ -1343,12 +1336,12 @@ contract QuarkWalletTest is Test { bytes memory revertsCode = new YulHelper().getCode("Reverts.sol/Reverts.json"); QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOp(aliceWallet, revertsCode, ScriptType.ScriptSource); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(Reverts.Whoops.selector)); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); } function testAtomicPing() public { @@ -1357,14 +1350,14 @@ contract QuarkWalletTest is Test { bytes memory ping = new YulHelper().getCode("Logger.sol/Logger.json"); QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOp(aliceWallet, ping, ScriptType.ScriptAddress); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); // TODO: Check who emitted. vm.expectEmit(false, false, false, true); emit Ping(55); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); } function testAtomicPingWithExternalSignature() public { @@ -1444,13 +1437,14 @@ contract QuarkWalletTest is Test { bytes memory sigHash = hex"1901420cb4769bd47ac11897b8b69b8d80a84b9ec8b69437cd42529681d583a6b5218c7d870a6510d1840f2ec48a08d65eb874fa8af841e45e3c9b8e5c244bdc015f"; (uint8 v, bytes32 r, bytes32 s) = vm.sign(alicePrivateKey, keccak256(sigHash)); + bytes memory signature = abi.encodePacked(r, s, v); // gas: meter execute vm.resumeGasMetering(); // TODO: Check who emitted. vm.expectEmit(true, true, true, true); emit Ping(0xdd); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); } function testAtomicIncrementer() public { @@ -1464,11 +1458,11 @@ contract QuarkWalletTest is Test { abi.encodeWithSignature("incrementCounter(address)", counter), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); assertEq(counter.number(), 3); } @@ -1486,9 +1480,9 @@ contract QuarkWalletTest is Test { abi.encodeCall(PrecompileCaller.ecrecoverCall, (testHash, vt, rt, st)), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); vm.resumeGasMetering(); - bytes memory rawOut = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory rawOut = aliceWallet.executeQuarkOperation(op, signature); bytes memory output = abi.decode(rawOut, (bytes)); assertEq(abi.decode(output, (address)), aliceAccount); } @@ -1505,9 +1499,9 @@ contract QuarkWalletTest is Test { // expiry: block.timestamp + 1000 // }); - // (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + // bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // vm.resumeGasMetering(); - // bytes memory rawOut = aliceWallet.executeQuarkOperation(op, v, r, s); + // bytes memory rawOut = aliceWallet.executeQuarkOperation(op, signature); // assertEq(abi.decode(rawOut, (address)), aliceAccount); // } @@ -1521,9 +1515,9 @@ contract QuarkWalletTest is Test { abi.encodeCall(PrecompileCaller.sha256Call, (numberToHash)), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); vm.resumeGasMetering(); - bytes memory rawOut = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory rawOut = aliceWallet.executeQuarkOperation(op, signature); bytes memory output = abi.decode(rawOut, (bytes)); assertEq(abi.decode(output, (bytes32)), sha256(abi.encodePacked(numberToHash))); } @@ -1539,9 +1533,9 @@ contract QuarkWalletTest is Test { // expiry: block.timestamp + 1000 // }); - // (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + // bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // vm.resumeGasMetering(); - // bytes memory output = aliceWallet.executeQuarkOperation(op, v, r, s); + // bytes memory output = aliceWallet.executeQuarkOperation(op, signature); // assertEq(abi.decode(output, (bytes32)), sha256(abi.encodePacked(numberToHash))); // } @@ -1555,9 +1549,9 @@ contract QuarkWalletTest is Test { abi.encodeCall(PrecompileCaller.ripemd160Call, (testBytes)), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); vm.resumeGasMetering(); - bytes memory output = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory output = aliceWallet.executeQuarkOperation(op, signature); assertEq(abi.decode(output, (bytes20)), ripemd160(testBytes)); } @@ -1571,9 +1565,9 @@ contract QuarkWalletTest is Test { // nonce: aliceWallet.nonceManager().nextNonce(address(aliceWallet)), // expiry: block.timestamp + 1000 // }); - // (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + // bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // vm.resumeGasMetering(); - // bytes memory output = aliceWallet.executeQuarkOperation(op, v, r, s); + // bytes memory output = aliceWallet.executeQuarkOperation(op, signature); // assertEq(bytes20(abi.decode(output, (bytes32)) << 96), ripemd160(testBytes)); // } @@ -1587,9 +1581,9 @@ contract QuarkWalletTest is Test { abi.encodeCall(PrecompileCaller.dataCopyCall, (testBytes)), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); vm.resumeGasMetering(); - bytes memory output = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory output = aliceWallet.executeQuarkOperation(op, signature); assertEq(abi.decode(output, (bytes)), testBytes); } @@ -1603,9 +1597,9 @@ contract QuarkWalletTest is Test { // nonce: aliceWallet.nonceManager().nextNonce(address(aliceWallet)), // expiry: block.timestamp + 1000 // }); - // (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + // bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // vm.resumeGasMetering(); - // bytes memory output = aliceWallet.executeQuarkOperation(op, v, r, s); + // bytes memory output = aliceWallet.executeQuarkOperation(op, signature); // assertEq(output, testBytes); // } @@ -1623,9 +1617,9 @@ contract QuarkWalletTest is Test { abi.encodeCall(PrecompileCaller.bigModExpCall, (base, exponent, modulus)), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); vm.resumeGasMetering(); - bytes memory output = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory output = aliceWallet.executeQuarkOperation(op, signature); assertEq(abi.decode(output, (bytes32)), expected); } @@ -1643,9 +1637,9 @@ contract QuarkWalletTest is Test { // nonce: aliceWallet.nonceManager().nextNonce(address(aliceWallet)), // expiry: block.timestamp + 1000 // }); - // (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + // bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // vm.resumeGasMetering(); - // bytes memory output = aliceWallet.executeQuarkOperation(op, v, r, s); + // bytes memory output = aliceWallet.executeQuarkOperation(op, signature); // assertEq(abi.decode(output, (bytes32)), expected); // } @@ -1658,9 +1652,9 @@ contract QuarkWalletTest is Test { abi.encodeCall(PrecompileCaller.bn256AddCall, (uint256(1), uint256(2), uint256(1), uint256(2))), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); vm.resumeGasMetering(); - bytes memory rawOut = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory rawOut = aliceWallet.executeQuarkOperation(op, signature); uint256[2] memory output = abi.decode(rawOut, (uint256[2])); assertEq(output[0], uint256(0x030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3)); assertEq(output[1], uint256(0x15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4)); @@ -1680,9 +1674,9 @@ contract QuarkWalletTest is Test { // nonce: aliceWallet.nonceManager().nextNonce(address(aliceWallet)), // expiry: block.timestamp + 1000 // }); - // (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + // bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // vm.resumeGasMetering(); - // bytes memory rawOut = aliceWallet.executeQuarkOperation(op, v, r, s); + // bytes memory rawOut = aliceWallet.executeQuarkOperation(op, signature); // uint256[2] memory output = abi.decode(rawOut, (uint256[2])); // assertEq(output[0], uint256(0x030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3)); // assertEq(output[1], uint256(0x15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4)); @@ -1697,9 +1691,9 @@ contract QuarkWalletTest is Test { abi.encodeCall(PrecompileCaller.bn256ScalarMulCall, (uint256(1), uint256(2), uint256(3))), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); vm.resumeGasMetering(); - bytes memory rawOut = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory rawOut = aliceWallet.executeQuarkOperation(op, signature); uint256[2] memory output = abi.decode(rawOut, (uint256[2])); assertEq(output[0], uint256(0x0769bf9ac56bea3ff40232bcb1b6bd159315d84715b8e679f2d355961915abf0)); assertEq(output[1], uint256(0x2ab799bee0489429554fdb7c8d086475319e63b40b9c5b57cdf1ff3dd9fe2261)); @@ -1718,9 +1712,9 @@ contract QuarkWalletTest is Test { // nonce: aliceWallet.nonceManager().nextNonce(address(aliceWallet)), // expiry: block.timestamp + 1000 // }); - // (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + // bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // vm.resumeGasMetering(); - // bytes memory rawOut = aliceWallet.executeQuarkOperation(op, v, r, s); + // bytes memory rawOut = aliceWallet.executeQuarkOperation(op, signature); // uint256[2] memory output = abi.decode(rawOut, (uint256[2])); // assertEq(output[0], uint256(0x0769bf9ac56bea3ff40232bcb1b6bd159315d84715b8e679f2d355961915abf0)); // assertEq(output[1], uint256(0x2ab799bee0489429554fdb7c8d086475319e63b40b9c5b57cdf1ff3dd9fe2261)); @@ -1757,9 +1751,9 @@ contract QuarkWalletTest is Test { abi.encodeCall(PrecompileCaller.blake2FCall, (rounds, h, m, t, f)), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); vm.resumeGasMetering(); - bytes memory rawOut = aliceWallet.executeQuarkOperation(op, v, r, s); + bytes memory rawOut = aliceWallet.executeQuarkOperation(op, signature); bytes32[2] memory output = abi.decode(rawOut, (bytes32[2])); assertEq(output[0], expected[0]); assertEq(output[1], expected[1]); @@ -1796,9 +1790,9 @@ contract QuarkWalletTest is Test { // nonce: aliceWallet.nonceManager().nextNonce(address(aliceWallet)), // expiry: block.timestamp + 1000 // }); - // (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + // bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // vm.resumeGasMetering(); - // bytes memory rawOut = aliceWallet.executeQuarkOperation(op, v, r, s); + // bytes memory rawOut = aliceWallet.executeQuarkOperation(op, signature); // bytes32[2] memory output = abi.decode(rawOut, (bytes32[2])); // assertEq(output[0], expected[0]); // assertEq(output[1], expected[1]); @@ -1811,10 +1805,10 @@ contract QuarkWalletTest is Test { vm.pauseGasMetering(); nonce = new QuarkOperationHelper().incrementNonce(nonce); QuarkWallet.QuarkOperation memory op = DummyQuarkOperation(address(uint160(i)), nonce); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); vm.resumeGasMetering(); vm.expectRevert(abi.encodeWithSelector(QuarkWallet.EmptyCode.selector)); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); } } diff --git a/test/quark-core/Reverts.t.sol b/test/quark-core/Reverts.t.sol index 58fb3a70..b16b1776 100644 --- a/test/quark-core/Reverts.t.sol +++ b/test/quark-core/Reverts.t.sol @@ -51,13 +51,13 @@ contract RevertsTest is Test { QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, revertsCode, abi.encodeWithSelector(Reverts.divideByZero.selector), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); // Reverts with "panic: division or modulo by zero (0x12)" vm.expectRevert(); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); } function testRevertsInteger() public { @@ -67,12 +67,12 @@ contract RevertsTest is Test { QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, revertsCode, abi.encodeWithSelector(Reverts.revertSeven.selector), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); vm.expectRevert(hex"0000000000000000000000000000000000000000000000000000000000000007"); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); } function testRevertsOutOfGas() public { @@ -82,13 +82,13 @@ contract RevertsTest is Test { QuarkWallet.QuarkOperation memory op = new QuarkOperationHelper().newBasicOpWithCalldata( aliceWallet, revertsCode, abi.encodeWithSelector(Reverts.outOfGas.selector), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); // Reverts with "EvmError: OutOfGas" vm.expectRevert(); - aliceWallet.executeQuarkOperation{gas: 300_000}(op, v, r, s); + aliceWallet.executeQuarkOperation{gas: 300_000}(op, signature); } function testRevertsInvalidOpcode() public { @@ -101,12 +101,12 @@ contract RevertsTest is Test { abi.encodeWithSelector(Reverts.invalidOpcode.selector, codeJar), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); // Reverts with "EvmError: InvalidFEOpcode" vm.expectRevert(); - aliceWallet.executeQuarkOperation(op, v, r, s); + aliceWallet.executeQuarkOperation(op, signature); } } diff --git a/test/quark-core/isValidSignature.t.sol b/test/quark-core/isValidSignature.t.sol index 917fc7c4..8cd27ede 100644 --- a/test/quark-core/isValidSignature.t.sol +++ b/test/quark-core/isValidSignature.t.sol @@ -69,7 +69,8 @@ contract isValidSignatureTest is Test { keccak256(abi.encodePacked("\x19\x01", new SignatureHelper().domainSeparator(address(wallet)), structHash)); bytes32 quarkMsgDigest = aliceWallet.getDigestForQuarkMessage(abi.encode(digest)); (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, quarkMsgDigest); - return (digest, abi.encodePacked(r, s, v)); + bytes memory signature = abi.encodePacked(r, s, v); + return (digest, signature); } function createPermit2Signature(uint256 privateKey, Permit2Helper.PermitSingle memory permitSingle) @@ -81,7 +82,8 @@ contract isValidSignatureTest is Test { bytes32 digest = Permit2Helper._hashTypedData(Permit2Helper.hash(permitSingle), domainSeparator); bytes32 quarkMsgDigest = aliceWallet.getDigestForQuarkMessage(abi.encode(digest)); (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, quarkMsgDigest); - return (digest, abi.encodePacked(r, s, v)); + bytes memory signature = abi.encodePacked(r, s, v); + return (digest, signature); } /* wallet owned by EOA */ diff --git a/test/quark-core/periphery/BatchExecutor.t.sol b/test/quark-core/periphery/BatchExecutor.t.sol index 897548c3..c9fc781f 100644 --- a/test/quark-core/periphery/BatchExecutor.t.sol +++ b/test/quark-core/periphery/BatchExecutor.t.sol @@ -69,31 +69,27 @@ contract BatchExecutorTest is Test { QuarkWallet.QuarkOperation memory aliceOp = new QuarkOperationHelper().newBasicOp(aliceWallet, ping, ScriptType.ScriptAddress); - (uint8 v0, bytes32 r0, bytes32 s0) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp); + bytes memory aliceSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp); QuarkWallet.QuarkOperation memory bobOp = new QuarkOperationHelper().newBasicOpWithCalldata( bobWallet, incrementer, abi.encodeWithSignature("incrementCounter(address)", counter), ScriptType.ScriptSource ); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(bobPrivateKey, bobWallet, bobOp); + bytes memory bobSignature = new SignatureHelper().signOp(bobPrivateKey, bobWallet, bobOp); // Construct list of operations and signatures BatchExecutor.OperationParams[] memory ops = new BatchExecutor.OperationParams[](2); ops[0] = BatchExecutor.OperationParams({ account: address(aliceWallet), op: aliceOp, - v: v0, - r: r0, - s: s0, + signature: aliceSignature, gasLimit: 0.1 ether }); ops[1] = BatchExecutor.OperationParams({ account: address(bobWallet), op: bobOp, - v: v1, - r: r1, - s: s1, + signature: bobSignature, gasLimit: 0.1 ether }); @@ -116,38 +112,32 @@ contract BatchExecutorTest is Test { QuarkWallet.QuarkOperation memory aliceOp = new QuarkOperationHelper().newBasicOp(aliceWallet, ping, ScriptType.ScriptAddress); - (uint8 v0, bytes32 r0, bytes32 s0) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp); + bytes memory aliceSignature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp); QuarkWallet.QuarkOperation memory bobOp = new QuarkOperationHelper().newBasicOp(bobWallet, reverts, ScriptType.ScriptSource); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(bobPrivateKey, bobWallet, bobOp); + bytes memory bobSignature = new SignatureHelper().signOp(bobPrivateKey, bobWallet, bobOp); QuarkWallet.QuarkOperation memory aliceOp2 = new QuarkOperationHelper().newBasicOp(aliceWallet, ping, ScriptType.ScriptAddress); - (uint8 v2, bytes32 r2, bytes32 s2) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp2); + bytes memory aliceSignature2 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp2); // Construct list of operations and signatures BatchExecutor.OperationParams[] memory ops = new BatchExecutor.OperationParams[](3); ops[0] = BatchExecutor.OperationParams({ account: address(aliceWallet), op: aliceOp, - v: v0, - r: r0, - s: s0, + signature: aliceSignature1, gasLimit: 0.1 ether }); ops[1] = BatchExecutor.OperationParams({ account: address(bobWallet), op: bobOp, - v: v1, - r: r1, - s: s1, + signature: bobSignature, gasLimit: 0.1 ether }); ops[2] = BatchExecutor.OperationParams({ account: address(aliceWallet), op: aliceOp2, - v: v2, - r: r2, - s: s2, + signature: aliceSignature2, gasLimit: 1 wei // To trigger OOG }); @@ -171,31 +161,27 @@ contract BatchExecutorTest is Test { QuarkWallet.QuarkOperation memory aliceOp = new QuarkOperationHelper().newBasicOp(aliceWallet, ping, ScriptType.ScriptAddress); - (uint8 v0, bytes32 r0, bytes32 s0) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp); + bytes memory aliceSignature = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp); QuarkWallet.QuarkOperation memory bobOp = new QuarkOperationHelper().newBasicOpWithCalldata( bobWallet, incrementer, abi.encodeWithSignature("incrementCounter(address)", counter), ScriptType.ScriptSource ); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(bobPrivateKey, bobWallet, bobOp); + bytes memory bobSignature = new SignatureHelper().signOp(bobPrivateKey, bobWallet, bobOp); // Construct list of operations and signatures BatchExecutor.OperationParams[] memory ops = new BatchExecutor.OperationParams[](2); ops[0] = BatchExecutor.OperationParams({ account: address(aliceWallet), op: aliceOp, - v: v0, - r: r0, - s: s0, + signature: aliceSignature, gasLimit: 0.1 ether }); ops[1] = BatchExecutor.OperationParams({ account: address(bobWallet), op: bobOp, - v: v1, - r: r1, - s: s1, + signature: bobSignature, gasLimit: 0.1 ether }); @@ -218,38 +204,32 @@ contract BatchExecutorTest is Test { QuarkWallet.QuarkOperation memory aliceOp = new QuarkOperationHelper().newBasicOp(aliceWallet, ping, ScriptType.ScriptAddress); - (uint8 v0, bytes32 r0, bytes32 s0) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp); + bytes memory aliceSignature1 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp); QuarkWallet.QuarkOperation memory bobOp = new QuarkOperationHelper().newBasicOp(bobWallet, reverts, ScriptType.ScriptSource); - (uint8 v1, bytes32 r1, bytes32 s1) = new SignatureHelper().signOp(bobPrivateKey, bobWallet, bobOp); + bytes memory bobSignature = new SignatureHelper().signOp(bobPrivateKey, bobWallet, bobOp); QuarkWallet.QuarkOperation memory aliceOp2 = new QuarkOperationHelper().newBasicOp(aliceWallet, ping, ScriptType.ScriptAddress); - (uint8 v2, bytes32 r2, bytes32 s2) = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp2); + bytes memory aliceSignature2 = new SignatureHelper().signOp(alicePrivateKey, aliceWallet, aliceOp2); // Construct list of operations and signatures BatchExecutor.OperationParams[] memory ops = new BatchExecutor.OperationParams[](3); ops[0] = BatchExecutor.OperationParams({ account: address(aliceWallet), op: aliceOp, - v: v0, - r: r0, - s: s0, + signature: aliceSignature1, gasLimit: 0.1 ether }); ops[1] = BatchExecutor.OperationParams({ account: address(bobWallet), op: bobOp, - v: v1, - r: r1, - s: s1, + signature: bobSignature, gasLimit: 0.1 ether }); ops[2] = BatchExecutor.OperationParams({ account: address(aliceWallet), op: aliceOp2, - v: v2, - r: r2, - s: s2, + signature: aliceSignature2, gasLimit: 1 wei // To trigger OOG }); diff --git a/test/quark-proxy/QuarkMinimalProxy.t.sol b/test/quark-proxy/QuarkMinimalProxy.t.sol index 165eb0cc..4502e380 100644 --- a/test/quark-proxy/QuarkMinimalProxy.t.sol +++ b/test/quark-proxy/QuarkMinimalProxy.t.sol @@ -59,12 +59,12 @@ contract QuarkMinimalProxyTest is Test { abi.encodeWithSignature("getSignerAndExecutor()"), ScriptType.ScriptAddress ); - (uint8 v, bytes32 r, bytes32 s) = + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, QuarkWallet(payable(aliceWalletProxy)), op); // gas: meter execute vm.resumeGasMetering(); - bytes memory result = QuarkWallet(payable(aliceWalletProxy)).executeQuarkOperation(op, v, r, s); + bytes memory result = QuarkWallet(payable(aliceWalletProxy)).executeQuarkOperation(op, signature); (address signer, address executor) = abi.decode(result, (address, address)); assertEq(signer, aliceAccount); assertEq(executor, address(0xabc)); diff --git a/test/quark-proxy/QuarkWalletProxyFactory.t.sol b/test/quark-proxy/QuarkWalletProxyFactory.t.sol index 383b9a5e..2595d07c 100644 --- a/test/quark-proxy/QuarkWalletProxyFactory.t.sol +++ b/test/quark-proxy/QuarkWalletProxyFactory.t.sol @@ -127,7 +127,7 @@ contract QuarkWalletProxyFactoryTest is Test { }); // alice signs the operation - (uint8 v, bytes32 r, bytes32 s) = + bytes memory signature = new SignatureHelper().signOpForAddress(alicePrivateKey, factory.walletAddressFor(alice, address(0)), op); assertEq(counter.number(), 0); @@ -139,7 +139,7 @@ contract QuarkWalletProxyFactoryTest is Test { vm.expectEmit(true, true, true, true); // it creates a wallet emit WalletDeploy(alice, address(0), factory.walletAddressFor(alice, address(0)), bytes32(0)); - factory.createAndExecute(alice, address(0), op, v, r, s); + factory.createAndExecute(alice, address(0), op, signature); // operation was executed assertEq(counter.number(), 3); @@ -175,7 +175,7 @@ contract QuarkWalletProxyFactoryTest is Test { bytes32 salt = bytes32("salty salt salt"); // alice signs the operation - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOpForAddress( + bytes memory signature = new SignatureHelper().signOpForAddress( alicePrivateKey, factory.walletAddressForSalt(alice, address(0), salt), op ); @@ -187,7 +187,7 @@ contract QuarkWalletProxyFactoryTest is Test { vm.expectEmit(true, true, true, true); // it creates a wallet (with salt) emit WalletDeploy(alice, address(0), factory.walletAddressForSalt(alice, address(0), salt), salt); - factory.createAndExecute(alice, address(0), salt, op, v, r, s); + factory.createAndExecute(alice, address(0), salt, op, signature); // operation was executed assertEq(counter.number(), 3); @@ -222,7 +222,7 @@ contract QuarkWalletProxyFactoryTest is Test { }); // alice signs the operation - (uint8 v, bytes32 r, bytes32 s) = + bytes memory signature = new SignatureHelper().signOpForAddress(alicePrivateKey, factory.walletAddressFor(alice, address(0)), op); assertEq(counter.number(), 0); @@ -236,7 +236,7 @@ contract QuarkWalletProxyFactoryTest is Test { factory.create(alice, address(0)); // operation is executed - factory.createAndExecute(alice, address(0), op, v, r, s); + factory.createAndExecute(alice, address(0), op, signature); // operation was executed assertEq(counter.number(), 3); @@ -290,20 +290,20 @@ contract QuarkWalletProxyFactoryTest is Test { bytes32[] memory opDigests = new bytes32[](2); opDigests[0] = op1Digest; opDigests[1] = op2Digest; - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); + bytes memory signature = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); vm.resumeGasMetering(); // call once vm.expectEmit(true, true, true, true); // it creates a wallet emit WalletDeploy(alice, address(0), aliceWalletAddress, bytes32(0)); - factory.createAndExecuteMulti(alice, address(0), op1, opDigests, v, r, s); + factory.createAndExecuteMulti(alice, address(0), op1, opDigests, signature); assertEq(counter.number(), 3); assertEq(nonceManager.submissions(aliceWalletAddress, op1.nonce), bytes32(type(uint256).max)); // call a second time - factory.createAndExecuteMulti(alice, address(0), op2, opDigests, v, r, s); + factory.createAndExecuteMulti(alice, address(0), op2, opDigests, signature); assertEq(counter.number(), 6); assertEq(nonceManager.submissions(aliceWalletAddress, op2.nonce), bytes32(type(uint256).max)); @@ -347,20 +347,20 @@ contract QuarkWalletProxyFactoryTest is Test { bytes32[] memory opDigests = new bytes32[](2); opDigests[0] = op1Digest; opDigests[1] = op2Digest; - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); + bytes memory signature = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); vm.resumeGasMetering(); // call once vm.expectEmit(true, true, true, true); // it creates a wallet (with salt) emit WalletDeploy(alice, address(0), aliceWalletAddress, salt); - factory.createAndExecuteMulti(alice, address(0), salt, op1, opDigests, v, r, s); + factory.createAndExecuteMulti(alice, address(0), salt, op1, opDigests, signature); assertEq(counter.number(), 3); assertEq(nonceManager.submissions(aliceWalletAddress, op1.nonce), bytes32(type(uint256).max)); // call a second time - factory.createAndExecuteMulti(alice, address(0), salt, op2, opDigests, v, r, s); + factory.createAndExecuteMulti(alice, address(0), salt, op2, opDigests, signature); assertEq(counter.number(), 6); assertEq(nonceManager.submissions(aliceWalletAddress, op2.nonce), bytes32(type(uint256).max)); @@ -407,7 +407,7 @@ contract QuarkWalletProxyFactoryTest is Test { bytes32[] memory opDigests = new bytes32[](2); opDigests[0] = op1Digest; opDigests[1] = op2Digest; - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); + bytes memory signature = new SignatureHelper().signMultiOp(alicePrivateKey, opDigests); // gas: meter create, createAndExecute vm.resumeGasMetering(); @@ -418,13 +418,13 @@ contract QuarkWalletProxyFactoryTest is Test { factory.create(alice, address(0)); // call once - factory.createAndExecuteMulti(alice, address(0), op1, opDigests, v, r, s); + factory.createAndExecuteMulti(alice, address(0), op1, opDigests, signature); assertEq(counter.number(), 3); assertEq(nonceManager.submissions(aliceWalletAddress, op1.nonce), bytes32(type(uint256).max)); // call a second time - factory.createAndExecuteMulti(alice, address(0), op2, opDigests, v, r, s); + factory.createAndExecuteMulti(alice, address(0), op2, opDigests, signature); assertEq(counter.number(), 6); assertEq(nonceManager.submissions(aliceWalletAddress, op2.nonce), bytes32(type(uint256).max)); @@ -452,7 +452,7 @@ contract QuarkWalletProxyFactoryTest is Test { isReplayable: false, expiry: block.timestamp + 1000 }); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOpForAddress(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOpForAddress(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); @@ -461,7 +461,7 @@ contract QuarkWalletProxyFactoryTest is Test { vm.expectEmit(true, true, true, true); // it creates a wallet emit WalletDeploy(alice, address(0), aliceWallet, bytes32(0)); - bytes memory result = factory.createAndExecute(alice, address(0), op, v, r, s); + bytes memory result = factory.createAndExecute(alice, address(0), op, signature); (address msgSender, address addressThis, uint256 msgValue) = abi.decode(result, (address, address, uint256)); assertEq(msgSender, address(factory)); @@ -489,14 +489,14 @@ contract QuarkWalletProxyFactoryTest is Test { isReplayable: false, expiry: block.timestamp + 1000 }); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOpForAddress(alicePrivateKey, aliceWallet, op); + bytes memory signature = new SignatureHelper().signOpForAddress(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); // we didn't include the script source in scriptSources and we never deployed it! vm.expectRevert(QuarkWallet.EmptyCode.selector); - factory.createAndExecute(alice, address(0), salt, op, v, r, s); + factory.createAndExecute(alice, address(0), salt, op, signature); // gas: do not meter set-up vm.pauseGasMetering(); @@ -504,7 +504,7 @@ contract QuarkWalletProxyFactoryTest is Test { // but if we do add it... op.scriptSources = new bytes[](1); op.scriptSources[0] = getMessageDetails; - (v, r, s) = new SignatureHelper().signOpForAddress(alicePrivateKey, aliceWallet, op); + (signature) = new SignatureHelper().signOpForAddress(alicePrivateKey, aliceWallet, op); // gas: meter execute vm.resumeGasMetering(); @@ -513,7 +513,7 @@ contract QuarkWalletProxyFactoryTest is Test { vm.expectEmit(true, true, true, true); // it creates a wallet emit WalletDeploy(alice, address(0), aliceWallet, salt); - bytes memory result = factory.createAndExecute(alice, address(0), salt, op, v, r, s); + bytes memory result = factory.createAndExecute(alice, address(0), salt, op, signature); (address msgSender, address addressThis, uint256 msgValue) = abi.decode(result, (address, address, uint256)); assertEq(msgSender, address(factory)); @@ -568,12 +568,12 @@ contract QuarkWalletProxyFactoryTest is Test { isReplayable: false, expiry: block.timestamp + 1000 }); - (uint8 v, bytes32 r, bytes32 s) = new SignatureHelper().signOp(alicePrivateKey, aliceWalletPrimary, op); + bytes memory signature = new SignatureHelper().signOp(alicePrivateKey, aliceWalletPrimary, op); // gas: meter execute vm.resumeGasMetering(); assertEq(counter.number(), 0); - aliceWalletPrimary.executeQuarkOperation(op, v, r, s); + aliceWalletPrimary.executeQuarkOperation(op, signature); assertEq(counter.number(), 7); } }