From a342006f41a8747aacafe953bcbeb5364a66ecbe Mon Sep 17 00:00:00 2001 From: Wilkins Chung Date: Tue, 28 May 2024 09:41:49 -0700 Subject: [PATCH 1/2] remove signing prefix which saves gas --- .../contracts/frameclaims/FramePaymaster.sol | 3 +-- .../contracts/lazyclaim/LazyPayableClaim.sol | 2 +- .../test/frameclaims/ERC1155FrameLazyClaim.t.sol | 3 +-- .../ERC1155LazyPayableClaimSignatureMinting.t.sol | 14 +++++++------- .../ERC721LazyPayableClaimSignatureMinting.t.sol | 14 +++++++------- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/packages/manifold/contracts/frameclaims/FramePaymaster.sol b/packages/manifold/contracts/frameclaims/FramePaymaster.sol index 3f568e6d..b3ccbd46 100644 --- a/packages/manifold/contracts/frameclaims/FramePaymaster.sol +++ b/packages/manifold/contracts/frameclaims/FramePaymaster.sol @@ -96,8 +96,7 @@ contract FramePaymaster is IFramePaymaster, AdminControl { function _validateCheckout(MintSubmission calldata submission) private { if (block.timestamp > submission.expiration) revert ExpiredSignature(); // Verify valid message based on input variables - bytes memory messageData = abi.encode(submission.extensionMints, submission.fid, submission.expiration, submission.nonce, msg.value); - bytes32 expectedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", messageData)); + bytes32 expectedMessage = keccak256(abi.encodePacked(abi.encode(submission.extensionMints, submission.fid, submission.expiration, submission.nonce, msg.value))); address signer = submission.message.recover(submission.signature); if (submission.message != expectedMessage || signer != _signer) revert InvalidSignature(); if (_usedNonces[submission.fid][submission.nonce]) revert InvalidNonce(); diff --git a/packages/manifold/contracts/lazyclaim/LazyPayableClaim.sol b/packages/manifold/contracts/lazyclaim/LazyPayableClaim.sol index d764241e..fa4b6e15 100644 --- a/packages/manifold/contracts/lazyclaim/LazyPayableClaim.sol +++ b/packages/manifold/contracts/lazyclaim/LazyPayableClaim.sol @@ -216,7 +216,7 @@ abstract contract LazyPayableClaim is ILazyPayableClaim, AdminControl { function _checkSignatureAndUpdate(address creatorContractAddress, uint256 instanceId, bytes calldata signature, bytes32 message, bytes32 nonce, address signingAddress, address mintFor, uint256 expiration, uint16 mintCount) internal { // Verify valid message based on input variables - bytes32 expectedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", creatorContractAddress, instanceId, nonce, mintFor, expiration, mintCount)); + bytes32 expectedMessage = keccak256(abi.encode(creatorContractAddress, instanceId, nonce, mintFor, expiration, mintCount)); // Verify nonce usage/re-use require(!_usedMessages[creatorContractAddress][instanceId][nonce], "Cannot replay transaction"); address signer = message.recover(signature); diff --git a/packages/manifold/test/frameclaims/ERC1155FrameLazyClaim.t.sol b/packages/manifold/test/frameclaims/ERC1155FrameLazyClaim.t.sol index 442780b0..543a2997 100644 --- a/packages/manifold/test/frameclaims/ERC1155FrameLazyClaim.t.sol +++ b/packages/manifold/test/frameclaims/ERC1155FrameLazyClaim.t.sol @@ -544,8 +544,7 @@ contract ERC1155FrameLazyClaimTest is Test { } function _constructSubmission(IFramePaymaster.ExtensionMint[] memory extensionMints, uint256 fid, uint256 expiration, uint256 nonce, uint256 totalAmount) internal view returns (IFramePaymaster.MintSubmission memory submission) { - bytes memory messageData = abi.encode(extensionMints, fid, expiration, nonce, totalAmount); - bytes32 message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", messageData)); + bytes32 message = keccak256(abi.encode(extensionMints, fid, expiration, nonce, totalAmount)); (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, message); bytes memory signature = abi.encodePacked(r, s, v); diff --git a/packages/manifold/test/lazyclaim/ERC1155LazyPayableClaimSignatureMinting.t.sol b/packages/manifold/test/lazyclaim/ERC1155LazyPayableClaimSignatureMinting.t.sol index 29bab6f5..357e406e 100644 --- a/packages/manifold/test/lazyclaim/ERC1155LazyPayableClaimSignatureMinting.t.sol +++ b/packages/manifold/test/lazyclaim/ERC1155LazyPayableClaimSignatureMinting.t.sol @@ -92,7 +92,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { uint16 mintCount = uint16(3); bytes32 nonce = "1"; uint expiration = uint(block.timestamp) + uint(120); - bytes32 message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + bytes32 message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, message); bytes memory signature = abi.encodePacked(r, s, v); @@ -123,7 +123,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { expiration ); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other, expiration, mintCount)); // Cannot replay same tx with same nonce, even with different mintfor vm.expectRevert("Cannot replay transaction"); @@ -139,7 +139,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { ); expiration = uint(block.timestamp) + uint(121); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); // Cannot replay same tx with same nonce, even with different expiration vm.expectRevert("Cannot replay transaction"); @@ -157,7 +157,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { // Bad message signed nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), nonce, uint256(1), other2, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), nonce, uint256(1), other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); @@ -177,7 +177,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { // Correct message, wrong signer nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey2, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.InvalidSignature.selector); @@ -195,7 +195,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { // Expired signature nonce = "2"; expiration = uint(0); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.ExpiredSignature.selector); @@ -239,7 +239,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { vm.startPrank(other); nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.MustUseSignatureMinting.selector); diff --git a/packages/manifold/test/lazyclaim/ERC721LazyPayableClaimSignatureMinting.t.sol b/packages/manifold/test/lazyclaim/ERC721LazyPayableClaimSignatureMinting.t.sol index 6520af44..c83204c4 100644 --- a/packages/manifold/test/lazyclaim/ERC721LazyPayableClaimSignatureMinting.t.sol +++ b/packages/manifold/test/lazyclaim/ERC721LazyPayableClaimSignatureMinting.t.sol @@ -93,7 +93,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { uint16 mintCount = uint16(3); bytes32 nonce = "1"; uint expiration = uint(block.timestamp) + uint(120); - bytes32 message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + bytes32 message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, message); bytes memory signature = abi.encodePacked(r, s, v); @@ -124,7 +124,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { expiration ); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other, expiration, mintCount)); // Cannot replay same tx with same nonce, even with different mintfor vm.expectRevert("Cannot replay transaction"); @@ -140,7 +140,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { ); expiration = uint(block.timestamp) + uint(121); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); // Cannot replay same tx with same nonce, even with different expiration vm.expectRevert("Cannot replay transaction"); @@ -158,7 +158,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { // Bad message signed nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), nonce, uint256(1), other2, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), nonce, uint256(1), other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); @@ -178,7 +178,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { // Correct message, wrong signer nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey2, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.InvalidSignature.selector); @@ -196,7 +196,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { // Expired signature nonce = "2"; expiration = uint(0); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.ExpiredSignature.selector); @@ -240,7 +240,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { vm.startPrank(other); nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.MustUseSignatureMinting.selector); From ba46f6587f8ec0069ae54cfebe6d6deabccedced Mon Sep 17 00:00:00 2001 From: Wilkins Chung Date: Tue, 28 May 2024 09:59:15 -0700 Subject: [PATCH 2/2] further gas improvements --- .../contracts/lazyclaim/LazyPayableClaim.sol | 2 +- .../ERC1155LazyPayableClaimSignatureMinting.t.sol | 14 +++++++------- .../ERC721LazyPayableClaimSignatureMinting.t.sol | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/manifold/contracts/lazyclaim/LazyPayableClaim.sol b/packages/manifold/contracts/lazyclaim/LazyPayableClaim.sol index fa4b6e15..b0c880d8 100644 --- a/packages/manifold/contracts/lazyclaim/LazyPayableClaim.sol +++ b/packages/manifold/contracts/lazyclaim/LazyPayableClaim.sol @@ -216,7 +216,7 @@ abstract contract LazyPayableClaim is ILazyPayableClaim, AdminControl { function _checkSignatureAndUpdate(address creatorContractAddress, uint256 instanceId, bytes calldata signature, bytes32 message, bytes32 nonce, address signingAddress, address mintFor, uint256 expiration, uint16 mintCount) internal { // Verify valid message based on input variables - bytes32 expectedMessage = keccak256(abi.encode(creatorContractAddress, instanceId, nonce, mintFor, expiration, mintCount)); + bytes32 expectedMessage = keccak256(abi.encodePacked(creatorContractAddress, instanceId, nonce, mintFor, expiration, mintCount)); // Verify nonce usage/re-use require(!_usedMessages[creatorContractAddress][instanceId][nonce], "Cannot replay transaction"); address signer = message.recover(signature); diff --git a/packages/manifold/test/lazyclaim/ERC1155LazyPayableClaimSignatureMinting.t.sol b/packages/manifold/test/lazyclaim/ERC1155LazyPayableClaimSignatureMinting.t.sol index 357e406e..102d66ad 100644 --- a/packages/manifold/test/lazyclaim/ERC1155LazyPayableClaimSignatureMinting.t.sol +++ b/packages/manifold/test/lazyclaim/ERC1155LazyPayableClaimSignatureMinting.t.sol @@ -92,7 +92,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { uint16 mintCount = uint16(3); bytes32 nonce = "1"; uint expiration = uint(block.timestamp) + uint(120); - bytes32 message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + bytes32 message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, message); bytes memory signature = abi.encodePacked(r, s, v); @@ -123,7 +123,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { expiration ); - message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other, expiration, mintCount)); // Cannot replay same tx with same nonce, even with different mintfor vm.expectRevert("Cannot replay transaction"); @@ -139,7 +139,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { ); expiration = uint(block.timestamp) + uint(121); - message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); // Cannot replay same tx with same nonce, even with different expiration vm.expectRevert("Cannot replay transaction"); @@ -157,7 +157,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { // Bad message signed nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encode(address(creatorCore), nonce, uint256(1), other2, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), nonce, uint256(1), other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); @@ -177,7 +177,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { // Correct message, wrong signer nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey2, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.InvalidSignature.selector); @@ -195,7 +195,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { // Expired signature nonce = "2"; expiration = uint(0); - message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.ExpiredSignature.selector); @@ -239,7 +239,7 @@ contract ERC1155LazyPayableClaimSignatureMintingTest is Test { vm.startPrank(other); nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.MustUseSignatureMinting.selector); diff --git a/packages/manifold/test/lazyclaim/ERC721LazyPayableClaimSignatureMinting.t.sol b/packages/manifold/test/lazyclaim/ERC721LazyPayableClaimSignatureMinting.t.sol index c83204c4..b831779f 100644 --- a/packages/manifold/test/lazyclaim/ERC721LazyPayableClaimSignatureMinting.t.sol +++ b/packages/manifold/test/lazyclaim/ERC721LazyPayableClaimSignatureMinting.t.sol @@ -93,7 +93,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { uint16 mintCount = uint16(3); bytes32 nonce = "1"; uint expiration = uint(block.timestamp) + uint(120); - bytes32 message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + bytes32 message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, message); bytes memory signature = abi.encodePacked(r, s, v); @@ -124,7 +124,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { expiration ); - message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other, expiration, mintCount)); // Cannot replay same tx with same nonce, even with different mintfor vm.expectRevert("Cannot replay transaction"); @@ -140,7 +140,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { ); expiration = uint(block.timestamp) + uint(121); - message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); // Cannot replay same tx with same nonce, even with different expiration vm.expectRevert("Cannot replay transaction"); @@ -158,7 +158,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { // Bad message signed nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encode(address(creatorCore), nonce, uint256(1), other2, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), nonce, uint256(1), other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); @@ -178,7 +178,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { // Correct message, wrong signer nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey2, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.InvalidSignature.selector); @@ -196,7 +196,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { // Expired signature nonce = "2"; expiration = uint(0); - message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.ExpiredSignature.selector); @@ -240,7 +240,7 @@ contract ERC721LazyPayableClaimSignatureMintingTest is Test { vm.startPrank(other); nonce = "2"; expiration = uint(block.timestamp) + uint(120); - message = keccak256(abi.encode(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); + message = keccak256(abi.encodePacked(address(creatorCore), uint256(1), nonce, other2, expiration, mintCount)); (v, r, s) = vm.sign(privateKey, message); signature = abi.encodePacked(r, s, v); vm.expectRevert(ILazyPayableClaim.MustUseSignatureMinting.selector);