From a4218355920b2263c041e0077ff1ab6f9955b972 Mon Sep 17 00:00:00 2001 From: Michael Standen Date: Tue, 23 Jul 2024 09:42:06 +1200 Subject: [PATCH] Support contract signers for Payments --- .gas-snapshot | 248 +++++++++++++++---------------- src/payments/Payments.sol | 9 +- src/utils/SignatureValidator.sol | 44 ++++++ test/_mocks/ERC1271Mock.sol | 35 +++++ test/payments/Payments.t.sol | 151 +++++++++++-------- 5 files changed, 296 insertions(+), 191 deletions(-) create mode 100644 src/utils/SignatureValidator.sol create mode 100644 test/_mocks/ERC1271Mock.sol diff --git a/.gas-snapshot b/.gas-snapshot index 7bcc192..1af3527 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,131 +1,131 @@ ClawbackMetadataTest:testDurationAndUnlocksAt() (gas: 500421) -ClawbackMetadataTest:testMetadataPropertiesERC1155((uint8,uint32,uint56,uint256),(bool,bool,uint56,address)) (runs: 1041, μ: 154827, ~: 143382) -ClawbackMetadataTest:testMetadataPropertiesERC20((uint8,uint32,uint56,uint256),(bool,bool,uint56,address)) (runs: 1041, μ: 160080, ~: 159977) -ClawbackMetadataTest:testMetadataPropertiesERC721((uint8,uint32,uint56,uint256),(bool,bool,uint56,address)) (runs: 1041, μ: 257466, ~: 253839) +ClawbackMetadataTest:testMetadataPropertiesERC1155((uint8,uint32,uint56,uint256),(bool,bool,uint56,address)) (runs: 1042, μ: 154798, ~: 143380) +ClawbackMetadataTest:testMetadataPropertiesERC20((uint8,uint32,uint56,uint256),(bool,bool,uint56,address)) (runs: 1042, μ: 160079, ~: 159973) +ClawbackMetadataTest:testMetadataPropertiesERC721((uint8,uint32,uint56,uint256),(bool,bool,uint56,address)) (runs: 1042, μ: 257462, ~: 253828) ClawbackMetadataTest:testSupportsInterface() (gas: 9592) -ClawbackTest:testAddTemplate(address,uint56,bool,bool) (runs: 1041, μ: 46910, ~: 46910) -ClawbackTest:testAddTemplateTransferer(address,address) (runs: 1041, μ: 77227, ~: 77227) -ClawbackTest:testAddTemplateTransfererInvalidCaller(address,address,bool,address) (runs: 1041, μ: 62737, ~: 49948) -ClawbackTest:testAddToWrap(address,uint8,uint256,uint256,uint56,address,uint64) (runs: 1036, μ: 284590, ~: 260535) -ClawbackTest:testAddToWrapInvalidWrappedId(uint256,uint256,address) (runs: 1041, μ: 13962, ~: 13962) -ClawbackTest:testClawback(uint8,uint256,uint256,uint56,address,address) (runs: 1041, μ: 278383, ~: 300591) -ClawbackTest:testClawbackAfterTransfer(uint8,uint256,uint256,uint56,address,address,address) (runs: 1041, μ: 306333, ~: 324569) -ClawbackTest:testClawbackDestructionOnly(uint8,uint256,uint256,uint56,address) (runs: 1041, μ: 279418, ~: 305386) -ClawbackTest:testClawbackDestructionOnlyInvalidReceiver(uint8,uint256,uint256,uint56,address,address) (runs: 1041, μ: 268092, ~: 292743) -ClawbackTest:testClawbackInvalidCaller(uint8,uint256,uint256,uint56,address,address) (runs: 1041, μ: 234620, ~: 259026) -ClawbackTest:testClawbackInvalidUnlocked(uint8,uint256,uint256,uint56,address,address) (runs: 1041, μ: 261895, ~: 286546) -ClawbackTest:testEmergencyClawback(uint8,uint256,uint256,uint56,address,address) (runs: 1041, μ: 290271, ~: 317480) -ClawbackTest:testEmergencyClawbackAfterTransfer(uint8,uint256,uint256,uint56,address,address,address) (runs: 1041, μ: 314686, ~: 340954) -ClawbackTest:testEmergencyClawbackDestructionOnly(uint8,uint256,uint256,uint56,address) (runs: 1041, μ: 290040, ~: 321415) -ClawbackTest:testEmergencyClawbackDestructionOnlyInvalidReceiver(uint8,uint256,uint256,uint56,address,address) (runs: 1041, μ: 268612, ~: 293263) -ClawbackTest:testEmergencyClawbackInvalidCaller(uint8,uint256,uint256,uint56,address,address) (runs: 1041, μ: 233688, ~: 258094) -ClawbackTest:testEmergencyClawbackInvalidUnlocked(uint8,uint256,uint256,uint56,address,address) (runs: 1041, μ: 262305, ~: 286956) -ClawbackTest:testPreventsOnERC1155Received(uint256,uint256) (runs: 1041, μ: 100410, ~: 100332) -ClawbackTest:testPreventsOnERC1155Received(uint256,uint256,uint256,uint256) (runs: 1041, μ: 159334, ~: 159413) -ClawbackTest:testPreventsOnERC721Received(uint256) (runs: 1041, μ: 118352, ~: 118352) +ClawbackTest:testAddTemplate(address,uint56,bool,bool) (runs: 1042, μ: 46910, ~: 46910) +ClawbackTest:testAddTemplateTransferer(address,address) (runs: 1042, μ: 77227, ~: 77227) +ClawbackTest:testAddTemplateTransfererInvalidCaller(address,address,bool,address) (runs: 1042, μ: 62725, ~: 49948) +ClawbackTest:testAddToWrap(address,uint8,uint256,uint256,uint56,address,uint64) (runs: 1036, μ: 284531, ~: 260535) +ClawbackTest:testAddToWrapInvalidWrappedId(uint256,uint256,address) (runs: 1042, μ: 13962, ~: 13962) +ClawbackTest:testClawback(uint8,uint256,uint256,uint56,address,address) (runs: 1042, μ: 278351, ~: 300591) +ClawbackTest:testClawbackAfterTransfer(uint8,uint256,uint256,uint56,address,address,address) (runs: 1042, μ: 306351, ~: 324569) +ClawbackTest:testClawbackDestructionOnly(uint8,uint256,uint256,uint56,address) (runs: 1042, μ: 279443, ~: 305386) +ClawbackTest:testClawbackDestructionOnlyInvalidReceiver(uint8,uint256,uint256,uint56,address,address) (runs: 1042, μ: 268057, ~: 292743) +ClawbackTest:testClawbackInvalidCaller(uint8,uint256,uint256,uint56,address,address) (runs: 1042, μ: 234585, ~: 259026) +ClawbackTest:testClawbackInvalidUnlocked(uint8,uint256,uint256,uint56,address,address) (runs: 1042, μ: 261860, ~: 286546) +ClawbackTest:testEmergencyClawback(uint8,uint256,uint256,uint56,address,address) (runs: 1042, μ: 290232, ~: 317480) +ClawbackTest:testEmergencyClawbackAfterTransfer(uint8,uint256,uint256,uint56,address,address,address) (runs: 1042, μ: 314711, ~: 340954) +ClawbackTest:testEmergencyClawbackDestructionOnly(uint8,uint256,uint256,uint56,address) (runs: 1042, μ: 290070, ~: 321415) +ClawbackTest:testEmergencyClawbackDestructionOnlyInvalidReceiver(uint8,uint256,uint256,uint56,address,address) (runs: 1042, μ: 268577, ~: 293263) +ClawbackTest:testEmergencyClawbackInvalidCaller(uint8,uint256,uint256,uint56,address,address) (runs: 1042, μ: 233653, ~: 258094) +ClawbackTest:testEmergencyClawbackInvalidUnlocked(uint8,uint256,uint256,uint56,address,address) (runs: 1042, μ: 262270, ~: 286956) +ClawbackTest:testPreventsOnERC1155Received(uint256,uint256) (runs: 1042, μ: 100410, ~: 100332) +ClawbackTest:testPreventsOnERC1155Received(uint256,uint256,uint256,uint256) (runs: 1042, μ: 159334, ~: 159413) +ClawbackTest:testPreventsOnERC721Received(uint256) (runs: 1042, μ: 118352, ~: 118352) ClawbackTest:testSupportsInterface() (gas: 13448) -ClawbackTest:testTransferByTransfererAsFrom(uint8,uint256,uint256,uint56,uint64,bool,address,bool) (runs: 1041, μ: 277573, ~: 300644) -ClawbackTest:testTransferByTransfererAsOperator(uint8,uint256,uint256,uint56,uint64,bool,address,address,bool) (runs: 1040, μ: 302372, ~: 326940) -ClawbackTest:testTransferByTransfererAsTo(uint8,uint256,uint256,uint56,uint64,bool,address,bool) (runs: 1041, μ: 278124, ~: 301195) -ClawbackTest:testTransferByTransfererNotApproved(uint8,uint256,uint256,uint56,uint64,bool,address,address,bool) (runs: 1040, μ: 269131, ~: 294659) -ClawbackTest:testTransferInvalidOperator(uint8,uint256,uint256,uint56,address,address,bool) (runs: 1040, μ: 270398, ~: 294441) -ClawbackTest:testTransferOpen(uint8,uint256,uint256,uint56,uint64,address) (runs: 1041, μ: 250199, ~: 275161) -ClawbackTest:testUnwrap(address,uint8,uint256,uint256,uint56,uint64) (runs: 1041, μ: 237205, ~: 243143) -ClawbackTest:testUnwrapAfterTransfer(address,uint8,uint256,uint256,uint56,uint64,address) (runs: 1041, μ: 272401, ~: 288712) -ClawbackTest:testUnwrapByInvalidOperator(address,address,uint8,uint256,uint256,uint56) (runs: 1041, μ: 233497, ~: 259371) -ClawbackTest:testUnwrapByOperator(address,address,uint8,uint256,uint256,uint56,uint64) (runs: 1041, μ: 268527, ~: 276227) -ClawbackTest:testUnwrapInvalidAmount(address,uint8,uint256,uint256,uint256,uint56) (runs: 1040, μ: 231931, ~: 258219) -ClawbackTest:testUnwrapInvalidToken(address,uint8,uint256,uint256,uint256,uint56) (runs: 1040, μ: 237306, ~: 263517) -ClawbackTest:testUnwrapTokenLocked(address,uint8,uint256,uint256,uint56) (runs: 1041, μ: 230428, ~: 255574) -ClawbackTest:testUpdateTemplateAdmin(address,address,uint56,bool,bool) (runs: 1040, μ: 76260, ~: 76260) +ClawbackTest:testTransferByTransfererAsFrom(uint8,uint256,uint256,uint56,uint64,bool,address,bool) (runs: 1042, μ: 277604, ~: 300644) +ClawbackTest:testTransferByTransfererAsOperator(uint8,uint256,uint256,uint56,uint64,bool,address,address,bool) (runs: 1041, μ: 302459, ~: 326987) +ClawbackTest:testTransferByTransfererAsTo(uint8,uint256,uint256,uint56,uint64,bool,address,bool) (runs: 1042, μ: 278155, ~: 301195) +ClawbackTest:testTransferByTransfererNotApproved(uint8,uint256,uint256,uint56,uint64,bool,address,address,bool) (runs: 1041, μ: 269219, ~: 294706) +ClawbackTest:testTransferInvalidOperator(uint8,uint256,uint256,uint56,address,address,bool) (runs: 1041, μ: 270418, ~: 294441) +ClawbackTest:testTransferOpen(uint8,uint256,uint256,uint56,uint64,address) (runs: 1042, μ: 250226, ~: 275161) +ClawbackTest:testUnwrap(address,uint8,uint256,uint256,uint56,uint64) (runs: 1042, μ: 237211, ~: 243143) +ClawbackTest:testUnwrapAfterTransfer(address,uint8,uint256,uint256,uint56,uint64,address) (runs: 1042, μ: 272454, ~: 288714) +ClawbackTest:testUnwrapByInvalidOperator(address,address,uint8,uint256,uint256,uint56) (runs: 1042, μ: 233521, ~: 259371) +ClawbackTest:testUnwrapByOperator(address,address,uint8,uint256,uint256,uint56,uint64) (runs: 1042, μ: 268557, ~: 276227) +ClawbackTest:testUnwrapInvalidAmount(address,uint8,uint256,uint256,uint256,uint56) (runs: 1041, μ: 232141, ~: 258219) +ClawbackTest:testUnwrapInvalidToken(address,uint8,uint256,uint256,uint256,uint56) (runs: 1041, μ: 237516, ~: 263517) +ClawbackTest:testUnwrapTokenLocked(address,uint8,uint256,uint256,uint56) (runs: 1042, μ: 230448, ~: 255574) +ClawbackTest:testUpdateTemplateAdmin(address,address,uint56,bool,bool) (runs: 1041, μ: 76260, ~: 76260) ClawbackTest:testUpdateTemplateAdminInvalidAdmin() (gas: 49830) -ClawbackTest:testUpdateTemplateAdminInvalidCaller(address,address,bool) (runs: 1041, μ: 63586, ~: 76202) -ClawbackTest:testUpdateTemplateInvalidCaller(address,address,bool,uint56,bool,bool) (runs: 1041, μ: 62130, ~: 50111) +ClawbackTest:testUpdateTemplateAdminInvalidCaller(address,address,bool) (runs: 1042, μ: 63573, ~: 76202) +ClawbackTest:testUpdateTemplateInvalidCaller(address,address,bool,uint56,bool,bool) (runs: 1042, μ: 62119, ~: 50111) ClawbackTest:testUpdateTemplateInvalidDestructionOnly() (gas: 49760) -ClawbackTest:testUpdateTemplateInvalidDuration(address,uint56,bool,bool,uint56) (runs: 1033, μ: 51268, ~: 51268) +ClawbackTest:testUpdateTemplateInvalidDuration(address,uint56,bool,bool,uint56) (runs: 1034, μ: 51268, ~: 51268) ClawbackTest:testUpdateTemplateInvalidTransferOpen() (gas: 50208) -ClawbackTest:testUpdateTemplateOperator(address,address,bool) (runs: 1041, μ: 67255, ~: 76985) -ClawbackTest:testUpdateTemplateOperatorInvalidCaller(address,address,bool,address,bool) (runs: 1041, μ: 63766, ~: 76084) -ClawbackTest:testUpdateTemplateValid(address,uint56,bool,bool,uint56,bool,bool) (runs: 1041, μ: 59337, ~: 59458) -ClawbackTest:testWrap(address,uint8,uint256,uint256,address) (runs: 1040, μ: 255931, ~: 281166) -ClawbackTest:testWrapInvalidAmount(address,uint8,uint256,uint256,address) (runs: 1041, μ: 209393, ~: 221861) -ClawbackTest:testWrapInvalidRewrapping(uint8,uint256,uint256,uint56,address) (runs: 1041, μ: 227199, ~: 254783) -ClawbackTest:testWrapInvalidTemplate(uint32,uint8,uint256,uint256,address) (runs: 1041, μ: 105357, ~: 115140) -ClawbackTest:testWrapInvalidTokenType(address,uint8,uint256,uint256) (runs: 1038, μ: 144404, ~: 152283) -ERC1155ItemsTest:testBatchMintOwner(uint256[],uint256[]) (runs: 1041, μ: 569729, ~: 584329) -ERC1155ItemsTest:testBatchMintWithRole(address,uint256[],uint256[]) (runs: 1040, μ: 655542, ~: 668399) -ERC1155ItemsTest:testBurnBatchInvalidOwnership(address,uint256[],uint256[]) (runs: 1040, μ: 230554, ~: 232670) -ERC1155ItemsTest:testBurnBatchSuccess(address,uint256[],uint256[],uint256[]) (runs: 1040, μ: 198187, ~: 196202) -ERC1155ItemsTest:testBurnInvalidOwnership(address,uint256,uint256,uint256) (runs: 1032, μ: 109575, ~: 110848) +ClawbackTest:testUpdateTemplateOperator(address,address,bool) (runs: 1042, μ: 67245, ~: 76985) +ClawbackTest:testUpdateTemplateOperatorInvalidCaller(address,address,bool,address,bool) (runs: 1042, μ: 63753, ~: 76084) +ClawbackTest:testUpdateTemplateValid(address,uint56,bool,bool,uint56,bool,bool) (runs: 1042, μ: 59337, ~: 59459) +ClawbackTest:testWrap(address,uint8,uint256,uint256,address) (runs: 1041, μ: 255957, ~: 281166) +ClawbackTest:testWrapInvalidAmount(address,uint8,uint256,uint256,address) (runs: 1042, μ: 209408, ~: 221861) +ClawbackTest:testWrapInvalidRewrapping(uint8,uint256,uint256,uint56,address) (runs: 1042, μ: 227230, ~: 254783) +ClawbackTest:testWrapInvalidTemplate(uint32,uint8,uint256,uint256,address) (runs: 1042, μ: 105367, ~: 115140) +ClawbackTest:testWrapInvalidTokenType(address,uint8,uint256,uint256) (runs: 1039, μ: 144455, ~: 152283) +ERC1155ItemsTest:testBatchMintOwner(uint256[],uint256[]) (runs: 1042, μ: 569738, ~: 584319) +ERC1155ItemsTest:testBatchMintWithRole(address,uint256[],uint256[]) (runs: 1041, μ: 655569, ~: 668406) +ERC1155ItemsTest:testBurnBatchInvalidOwnership(address,uint256[],uint256[]) (runs: 1041, μ: 230557, ~: 232636) +ERC1155ItemsTest:testBurnBatchSuccess(address,uint256[],uint256[],uint256[]) (runs: 1041, μ: 198214, ~: 196248) +ERC1155ItemsTest:testBurnInvalidOwnership(address,uint256,uint256,uint256) (runs: 1033, μ: 109576, ~: 110848) ERC1155ItemsTest:testBurnSuccess(address,uint256,uint256,uint256) (runs: 1033, μ: 125834, ~: 125894) ERC1155ItemsTest:testContractURI() (gas: 83132) ERC1155ItemsTest:testDefaultRoyalty(address,uint96,uint256) (runs: 1028, μ: 41446, ~: 41446) -ERC1155ItemsTest:testFactoryDetermineAddress(address,address,string,string,string,address,uint96) (runs: 1040, μ: 6718898, ~: 6718702) -ERC1155ItemsTest:testMetadataInvalid(address) (runs: 1041, μ: 66770, ~: 66770) +ERC1155ItemsTest:testFactoryDetermineAddress(address,address,string,string,string,address,uint96) (runs: 1041, μ: 6718856, ~: 6718701) +ERC1155ItemsTest:testMetadataInvalid(address) (runs: 1042, μ: 66770, ~: 66770) ERC1155ItemsTest:testMetadataOwner() (gas: 43862) -ERC1155ItemsTest:testMetadataWithRole(address) (runs: 1041, μ: 117392, ~: 117392) -ERC1155ItemsTest:testMintInvalidRole(address) (runs: 1041, μ: 122424, ~: 122424) -ERC1155ItemsTest:testMintOwner(uint256,uint256) (runs: 1041, μ: 104895, ~: 104895) -ERC1155ItemsTest:testMintWithRole(address,uint256,uint256) (runs: 1041, μ: 187904, ~: 188535) +ERC1155ItemsTest:testMetadataWithRole(address) (runs: 1042, μ: 117392, ~: 117392) +ERC1155ItemsTest:testMintInvalidRole(address) (runs: 1042, μ: 122424, ~: 122424) +ERC1155ItemsTest:testMintOwner(uint256,uint256) (runs: 1042, μ: 104895, ~: 104895) +ERC1155ItemsTest:testMintWithRole(address,uint256,uint256) (runs: 1042, μ: 187904, ~: 188535) ERC1155ItemsTest:testOwnerHasRoles() (gas: 46365) ERC1155ItemsTest:testReinitializeFails() (gas: 27964) -ERC1155ItemsTest:testRoyaltyInvalidRole(address,uint256,address,uint96,uint256) (runs: 1029, μ: 121054, ~: 121054) -ERC1155ItemsTest:testRoyaltyWithRole(address,uint256,address,uint96,uint256) (runs: 1029, μ: 154172, ~: 154355) +ERC1155ItemsTest:testRoyaltyInvalidRole(address,uint256,address,uint96,uint256) (runs: 1030, μ: 121054, ~: 121054) +ERC1155ItemsTest:testRoyaltyWithRole(address,uint256,address,uint96,uint256) (runs: 1030, μ: 154172, ~: 154355) ERC1155ItemsTest:testSelectorCollision() (gas: 82659) ERC1155ItemsTest:testSupportsInterface() (gas: 34330) -ERC1155ItemsTest:testTokenRoyalty(uint256,address,uint96,uint256) (runs: 1028, μ: 65139, ~: 65139) -ERC1155SaleTest:testERC20Mint(bool,address,uint256,uint256) (runs: 1041, μ: 3387932, ~: 716247) -ERC1155SaleTest:testERC20MintFailPaidETH(bool,address,uint256,uint256) (runs: 1041, μ: 3300418, ~: 623141) -ERC1155SaleTest:testFactoryDetermineAddress(address,address,address) (runs: 1041, μ: 5458400, ~: 5458400) -ERC1155SaleTest:testFreeGlobalMint(bool,address,uint256,uint256) (runs: 1041, μ: 2833268, ~: 162267) -ERC1155SaleTest:testFreeTokenMint(bool,address,uint256,uint256) (runs: 1041, μ: 2880799, ~: 209073) -ERC1155SaleTest:testMerkleFailBadProof(address[],address,uint256,bool) (runs: 1041, μ: 285563, ~: 293418) -ERC1155SaleTest:testMerkleFailNoProof(address[],address,uint256,bool) (runs: 1041, μ: 281405, ~: 288677) -ERC1155SaleTest:testMerkleReuseFail(address[],uint256,uint256,bool) (runs: 1039, μ: 414568, ~: 423111) -ERC1155SaleTest:testMerkleSuccess(address[],uint256,uint256,bool) (runs: 1039, μ: 406197, ~: 414742) -ERC1155SaleTest:testMerkleSuccessGlobalMultiple(address[],uint256,uint256[]) (runs: 1039, μ: 464536, ~: 463161) -ERC1155SaleTest:testMintExpiredGlobalFail(bool,address,uint256,uint256,uint64,uint64) (runs: 1041, μ: 2841749, ~: 97515) -ERC1155SaleTest:testMintExpiredSingleFail(bool,address,uint256,uint256,uint64,uint64) (runs: 1041, μ: 2842080, ~: 97844) -ERC1155SaleTest:testMintFailMaxTotal(bool,address,uint256,uint256) (runs: 1041, μ: 2864018, ~: 185244) -ERC1155SaleTest:testMintFailWrongPaymentToken(bool,address,uint256,uint256,address) (runs: 1041, μ: 3351515, ~: 609030) -ERC1155SaleTest:testMintGlobalSuccess(bool,address,uint256,uint256) (runs: 1041, μ: 2862089, ~: 191088) -ERC1155SaleTest:testMintGlobalSupplyExceeded(bool,address,uint256,uint256,uint256) (runs: 1041, μ: 2914849, ~: 5661830) -ERC1155SaleTest:testMintGroupSuccess(bool,address,uint256,uint256) (runs: 1041, μ: 2967616, ~: 295888) -ERC1155SaleTest:testMintInactiveFail(bool,address,uint256,uint256) (runs: 1041, μ: 2722508, ~: 47156) -ERC1155SaleTest:testMintInactiveInGroupFail(bool,address,uint256,uint256) (runs: 1041, μ: 2779487, ~: 104376) -ERC1155SaleTest:testMintInactiveSingleFail(bool,address,uint256,uint256) (runs: 1041, μ: 2777405, ~: 102294) -ERC1155SaleTest:testMintSingleSuccess(bool,address,uint256,uint256) (runs: 1041, μ: 2862184, ~: 191180) -ERC1155SaleTest:testMintTokenSupplyExceeded(bool,address,uint256,uint256,uint256) (runs: 1041, μ: 2913322, ~: 5660306) +ERC1155ItemsTest:testTokenRoyalty(uint256,address,uint96,uint256) (runs: 1029, μ: 65139, ~: 65139) +ERC1155SaleTest:testERC20Mint(bool,address,uint256,uint256) (runs: 1042, μ: 3385368, ~: 716247) +ERC1155SaleTest:testERC20MintFailPaidETH(bool,address,uint256,uint256) (runs: 1042, μ: 3297849, ~: 623141) +ERC1155SaleTest:testFactoryDetermineAddress(address,address,address) (runs: 1042, μ: 5458400, ~: 5458400) +ERC1155SaleTest:testFreeGlobalMint(bool,address,uint256,uint256) (runs: 1042, μ: 2830704, ~: 162267) +ERC1155SaleTest:testFreeTokenMint(bool,address,uint256,uint256) (runs: 1042, μ: 2878235, ~: 209073) +ERC1155SaleTest:testMerkleFailBadProof(address[],address,uint256,bool) (runs: 1042, μ: 285457, ~: 293305) +ERC1155SaleTest:testMerkleFailNoProof(address[],address,uint256,bool) (runs: 1042, μ: 281299, ~: 288620) +ERC1155SaleTest:testMerkleReuseFail(address[],uint256,uint256,bool) (runs: 1040, μ: 414365, ~: 422898) +ERC1155SaleTest:testMerkleSuccess(address[],uint256,uint256,bool) (runs: 1040, μ: 405994, ~: 414442) +ERC1155SaleTest:testMerkleSuccessGlobalMultiple(address[],uint256,uint256[]) (runs: 1040, μ: 464742, ~: 463828) +ERC1155SaleTest:testMintExpiredGlobalFail(bool,address,uint256,uint256,uint64,uint64) (runs: 1042, μ: 2839116, ~: 97515) +ERC1155SaleTest:testMintExpiredSingleFail(bool,address,uint256,uint256,uint64,uint64) (runs: 1042, μ: 2839446, ~: 97844) +ERC1155SaleTest:testMintFailMaxTotal(bool,address,uint256,uint256) (runs: 1042, μ: 2861447, ~: 185244) +ERC1155SaleTest:testMintFailWrongPaymentToken(bool,address,uint256,uint256,address) (runs: 1042, μ: 3348864, ~: 609030) +ERC1155SaleTest:testMintGlobalSuccess(bool,address,uint256,uint256) (runs: 1042, μ: 2859525, ~: 191088) +ERC1155SaleTest:testMintGlobalSupplyExceeded(bool,address,uint256,uint256,uint256) (runs: 1042, μ: 2912176, ~: 5661813) +ERC1155SaleTest:testMintGroupSuccess(bool,address,uint256,uint256) (runs: 1042, μ: 2965052, ~: 295888) +ERC1155SaleTest:testMintInactiveFail(bool,address,uint256,uint256) (runs: 1042, μ: 2719940, ~: 47156) +ERC1155SaleTest:testMintInactiveInGroupFail(bool,address,uint256,uint256) (runs: 1042, μ: 2776919, ~: 104376) +ERC1155SaleTest:testMintInactiveSingleFail(bool,address,uint256,uint256) (runs: 1042, μ: 2774838, ~: 102294) +ERC1155SaleTest:testMintSingleSuccess(bool,address,uint256,uint256) (runs: 1042, μ: 2859620, ~: 191180) +ERC1155SaleTest:testMintTokenSupplyExceeded(bool,address,uint256,uint256,uint256) (runs: 1042, μ: 2910649, ~: 5660289) ERC1155SaleTest:testSelectorCollision() (gas: 51971) ERC1155SaleTest:testSupportsInterface() (gas: 10896) -ERC1155SaleTest:testWithdrawERC20(bool,address,uint256) (runs: 1040, μ: 3107491, ~: 456613) -ERC1155SaleTest:testWithdrawETH(bool,address,uint256) (runs: 1040, μ: 2699129, ~: 46905) -ERC1155SaleTest:testWithdrawFail(bool,address,uint256) (runs: 1041, μ: 3067629, ~: 460853) +ERC1155SaleTest:testWithdrawERC20(bool,address,uint256) (runs: 1041, μ: 3110263, ~: 456613) +ERC1155SaleTest:testWithdrawETH(bool,address,uint256) (runs: 1041, μ: 2701902, ~: 46905) +ERC1155SaleTest:testWithdrawFail(bool,address,uint256) (runs: 1042, μ: 3065127, ~: 460853) ERC20ItemsTest:testBurnInsufficient(address,uint256,uint256) (runs: 1032, μ: 80735, ~: 82008) -ERC20ItemsTest:testBurnSuccess(address,uint256,uint256) (runs: 1032, μ: 90151, ~: 90217) -ERC20ItemsTest:testFactoryDetermineAddress(address,address,string,string,uint8) (runs: 1040, μ: 5250740, ~: 5251395) +ERC20ItemsTest:testBurnSuccess(address,uint256,uint256) (runs: 1033, μ: 90151, ~: 90217) +ERC20ItemsTest:testFactoryDetermineAddress(address,address,string,string,uint8) (runs: 1041, μ: 5250740, ~: 5251395) ERC20ItemsTest:testInitValues() (gas: 38152) -ERC20ItemsTest:testMintInvalidRole(address,uint256) (runs: 1040, μ: 67299, ~: 67299) -ERC20ItemsTest:testMintOwner(uint256) (runs: 1041, μ: 80616, ~: 80616) -ERC20ItemsTest:testMintWithRole(address,uint256) (runs: 1040, μ: 164429, ~: 164429) +ERC20ItemsTest:testMintInvalidRole(address,uint256) (runs: 1041, μ: 67299, ~: 67299) +ERC20ItemsTest:testMintOwner(uint256) (runs: 1042, μ: 80616, ~: 80616) +ERC20ItemsTest:testMintWithRole(address,uint256) (runs: 1041, μ: 164429, ~: 164429) ERC20ItemsTest:testOwnerHasRoles() (gas: 35476) ERC20ItemsTest:testReinitializeFails() (gas: 26988) ERC20ItemsTest:testSelectorCollision() (gas: 61795) ERC20ItemsTest:testSupportsInterface() (gas: 31231) -ERC721ItemsTest:testBurnBatchInvalidOwnership(address) (runs: 1040, μ: 112693, ~: 112693) -ERC721ItemsTest:testBurnBatchSuccess(address) (runs: 1040, μ: 174303, ~: 174303) -ERC721ItemsTest:testBurnInvalidOwnership(address) (runs: 1040, μ: 109870, ~: 109870) -ERC721ItemsTest:testBurnSuccess(address) (runs: 1040, μ: 138108, ~: 138108) +ERC721ItemsTest:testBurnBatchInvalidOwnership(address) (runs: 1041, μ: 112693, ~: 112693) +ERC721ItemsTest:testBurnBatchSuccess(address) (runs: 1041, μ: 174303, ~: 174303) +ERC721ItemsTest:testBurnInvalidOwnership(address) (runs: 1041, μ: 109870, ~: 109870) +ERC721ItemsTest:testBurnSuccess(address) (runs: 1041, μ: 138108, ~: 138108) ERC721ItemsTest:testContractURI() (gas: 85853) ERC721ItemsTest:testDefaultRoyalty(address,uint96,uint256) (runs: 1029, μ: 41423, ~: 41423) -ERC721ItemsTest:testFactoryDetermineAddress(address,address,string,string,string,string,address,uint96) (runs: 1039, μ: 6792265, ~: 6793149) -ERC721ItemsTest:testMetadataInvalid(address) (runs: 1041, μ: 69188, ~: 69188) +ERC721ItemsTest:testFactoryDetermineAddress(address,address,string,string,string,string,address,uint96) (runs: 1040, μ: 6792246, ~: 6793149) +ERC721ItemsTest:testMetadataInvalid(address) (runs: 1042, μ: 69188, ~: 69188) ERC721ItemsTest:testMetadataOwner() (gas: 130207) -ERC721ItemsTest:testMetadataWithRole(address) (runs: 1040, μ: 117459, ~: 117459) -ERC721ItemsTest:testMintInvalidRole(address) (runs: 1041, μ: 68300, ~: 68300) +ERC721ItemsTest:testMetadataWithRole(address) (runs: 1041, μ: 117459, ~: 117459) +ERC721ItemsTest:testMintInvalidRole(address) (runs: 1042, μ: 68300, ~: 68300) ERC721ItemsTest:testMintMultiple() (gas: 116419) ERC721ItemsTest:testMintOwner() (gas: 103222) -ERC721ItemsTest:testMintWithRole(address) (runs: 1040, μ: 187284, ~: 187284) +ERC721ItemsTest:testMintWithRole(address) (runs: 1041, μ: 187284, ~: 187284) ERC721ItemsTest:testNameAndSymbol() (gas: 90129) ERC721ItemsTest:testOwnerHasRoles() (gas: 46710) ERC721ItemsTest:testReinitializeFails() (gas: 28529) @@ -139,12 +139,12 @@ ERC721SaleTest:testERC20Mint(bool,address,uint256) (runs: 1024, μ: 3275957, ~: ERC721SaleTest:testERC20MintFailMaxTotal(bool,address,uint256) (runs: 1024, μ: 3163850, ~: 5724070) ERC721SaleTest:testERC20MintFailPaidETH(bool,address,uint256) (runs: 1024, μ: 3147745, ~: 5707965) ERC721SaleTest:testETHMintFailMaxTotal(bool,address,uint256) (runs: 1024, μ: 2666765, ~: 5227053) -ERC721SaleTest:testFactoryDetermineAddress(address,address,address) (runs: 1041, μ: 5065069, ~: 5065069) +ERC721SaleTest:testFactoryDetermineAddress(address,address,address) (runs: 1042, μ: 5065069, ~: 5065069) ERC721SaleTest:testFreeMint(bool,address,uint256) (runs: 1024, μ: 2723224, ~: 5276497) -ERC721SaleTest:testMerkleFailBadProof(address[],address) (runs: 1041, μ: 290525, ~: 296730) -ERC721SaleTest:testMerkleFailNoProof(address[],address) (runs: 1041, μ: 286530, ~: 292296) -ERC721SaleTest:testMerkleReuseFail(address[],uint256) (runs: 1041, μ: 387007, ~: 381695) -ERC721SaleTest:testMerkleSuccess(address[],uint256) (runs: 1041, μ: 380194, ~: 374890) +ERC721SaleTest:testMerkleFailBadProof(address[],address) (runs: 1042, μ: 290414, ~: 296604) +ERC721SaleTest:testMerkleFailNoProof(address[],address) (runs: 1042, μ: 286419, ~: 292191) +ERC721SaleTest:testMerkleReuseFail(address[],uint256) (runs: 1042, μ: 386902, ~: 381426) +ERC721SaleTest:testMerkleSuccess(address[],uint256) (runs: 1042, μ: 380090, ~: 374621) ERC721SaleTest:testMintExpiredFail(bool,address,uint256,uint64,uint64) (runs: 1024, μ: 2676271, ~: 112433) ERC721SaleTest:testMintFailWrongPaymentToken(bool,address,uint256,address) (runs: 1024, μ: 3156015, ~: 5681075) ERC721SaleTest:testMintInactiveFail(bool,address,uint256) (runs: 1024, μ: 2620207, ~: 5180746) @@ -152,24 +152,24 @@ ERC721SaleTest:testMintSuccess(bool,address,uint256) (runs: 1024, μ: 2752285, ~ ERC721SaleTest:testMintSupplyExceeded(bool,address,uint256,uint256) (runs: 1024, μ: 2656473, ~: 131387) ERC721SaleTest:testSelectorCollision() (gas: 44619) ERC721SaleTest:testSupportsInterface() (gas: 10887) -ERC721SaleTest:testWithdrawERC20(bool,address,uint256) (runs: 1040, μ: 2908423, ~: 455750) -ERC721SaleTest:testWithdrawETH(bool,address,uint256) (runs: 1040, μ: 2500374, ~: 46368) -ERC721SaleTest:testWithdrawFail(bool,address,uint256) (runs: 1041, μ: 2879723, ~: 460740) -PaymentsTest:testMakePaymentExpired(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),uint64) (runs: 1030, μ: 133238, ~: 141494) -PaymentsTest:testMakePaymentFailedChainedCall(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),bytes) (runs: 1040, μ: 162398, ~: 179047) -PaymentsTest:testMakePaymentInvalidPayment(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string)) (runs: 1040, μ: 71548, ~: 71420) -PaymentsTest:testMakePaymentInvalidSignature(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),bytes) (runs: 1041, μ: 26209, ~: 26170) -PaymentsTest:testMakePaymentInvalidTokenSettingsERC20(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),uint256) (runs: 1040, μ: 65397, ~: 65456) -PaymentsTest:testMakePaymentInvalidTokenSettingsERC721(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string)) (runs: 1040, μ: 65160, ~: 65224) -PaymentsTest:testMakePaymentSuccess(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string)) (runs: 1040, μ: 162837, ~: 180604) -PaymentsTest:testMakePaymentSuccessChainedCall(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string)) (runs: 1040, μ: 236988, ~: 237341) -PaymentsTest:testMakePaymentSuccessMultiplePaymentRecips(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),address) (runs: 1035, μ: 189087, ~: 172814) -PaymentsTest:testPerformChainedCallInvalidCall(bytes) (runs: 1041, μ: 14950, ~: 14906) -PaymentsTest:testPerformChainedCallInvalidCaller(address,uint8,uint256,uint256,address) (runs: 1041, μ: 22958, ~: 22922) -PaymentsTest:testPerformChainedCallSuccess(uint8,uint256,uint256,address) (runs: 1041, μ: 89054, ~: 98559) -PaymentsTest:testSupportsInterface() (gas: 10757) -PaymentsTest:testUpdateSignerInvalidSender(address,address) (runs: 1041, μ: 13776, ~: 13776) -PaymentsTest:testUpdateSignerSuccess(address) (runs: 1041, μ: 19194, ~: 19229) +ERC721SaleTest:testWithdrawERC20(bool,address,uint256) (runs: 1041, μ: 2906067, ~: 455750) +ERC721SaleTest:testWithdrawETH(bool,address,uint256) (runs: 1041, μ: 2498016, ~: 46368) +ERC721SaleTest:testWithdrawFail(bool,address,uint256) (runs: 1042, μ: 2877401, ~: 460740) +PaymentsTest:testMakePaymentExpired(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),uint64,bool) (runs: 1034, μ: 149720, ~: 144121) +PaymentsTest:testMakePaymentFailedChainedCall(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),bytes,bool) (runs: 1039, μ: 178740, ~: 180936) +PaymentsTest:testMakePaymentInvalidPayment(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),bool) (runs: 1040, μ: 88805, ~: 103500) +PaymentsTest:testMakePaymentInvalidSignature(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),bool) (runs: 1042, μ: 40413, ~: 45984) +PaymentsTest:testMakePaymentInvalidTokenSettingsERC20(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),uint256,bool) (runs: 1040, μ: 81810, ~: 97299) +PaymentsTest:testMakePaymentInvalidTokenSettingsERC721(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),bool) (runs: 1040, μ: 81910, ~: 97020) +PaymentsTest:testMakePaymentSuccess(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),bool) (runs: 1040, μ: 181576, ~: 182624) +PaymentsTest:testMakePaymentSuccessChainedCall(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),bool) (runs: 1039, μ: 255238, ~: 252820) +PaymentsTest:testMakePaymentSuccessMultiplePaymentRecips(address,(uint256,address,uint8,address,uint256,(address,uint256),uint64,string),address,bool) (runs: 1038, μ: 205830, ~: 205875) +PaymentsTest:testPerformChainedCallInvalidCall(bytes,bool) (runs: 1042, μ: 43139, ~: 56893) +PaymentsTest:testPerformChainedCallInvalidSignature(address,uint8,uint256,uint256,address,bool) (runs: 1042, μ: 39847, ~: 35313) +PaymentsTest:testPerformChainedCallSuccess(uint8,uint256,uint256,address,bool) (runs: 1042, μ: 114179, ~: 116230) +PaymentsTest:testSupportsInterface() (gas: 10790) +PaymentsTest:testUpdateSignerInvalidSender(address,address) (runs: 1042, μ: 13790, ~: 13790) +PaymentsTest:testUpdateSignerSuccess(address) (runs: 1042, μ: 19268, ~: 19287) SequenceProxyFactoryTest:testAddressCompute() (gas: 1021270) SequenceProxyFactoryTest:testDeployProxy() (gas: 1021687) SequenceProxyFactoryTest:testDeployProxyAfterUpgrade() (gas: 1033631) diff --git a/src/payments/Payments.sol b/src/payments/Payments.sol index 29bbe51..4a27664 100644 --- a/src/payments/Payments.sol +++ b/src/payments/Payments.sol @@ -6,14 +6,13 @@ import {IPayments, IPaymentsFunctions} from "./IPayments.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {IERC165} from "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol"; +import {SignatureValidator} from "../utils/SignatureValidator.sol"; import {IERC721Transfer} from "../tokens/common/IERC721Transfer.sol"; import {IERC1155} from "@0xsequence/erc-1155/contracts/interfaces/IERC1155.sol"; - import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol"; -import {ECDSA} from "solady/utils/ECDSA.sol"; contract Payments is Ownable, IPayments, IERC165 { - using ECDSA for bytes32; + using SignatureValidator for bytes32; address public signer; @@ -78,7 +77,7 @@ contract Payments is Ownable, IPayments, IERC165 { returns (bool) { bytes32 messageHash = hashPaymentDetails(paymentDetails); - address sigSigner = messageHash.recoverCalldata(signature); + address sigSigner = messageHash.recoverSigner(signature); return sigSigner == signer; } @@ -120,7 +119,7 @@ contract Payments is Ownable, IPayments, IERC165 { returns (bool) { bytes32 messageHash = hashChainedCallDetails(chainedCallDetails); - address sigSigner = messageHash.recoverCalldata(signature); + address sigSigner = messageHash.recoverSigner(signature); return sigSigner == signer; } diff --git a/src/utils/SignatureValidator.sol b/src/utils/SignatureValidator.sol new file mode 100644 index 0000000..94e9e4b --- /dev/null +++ b/src/utils/SignatureValidator.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.19; + +import {ECDSA} from "solady/utils/ECDSA.sol"; +import {IERC1271Wallet} from "@0xsequence/erc-1155/contracts/interfaces/IERC1271Wallet.sol"; + +library SignatureValidator { + using ECDSA for bytes32; + + uint8 private constant SIG_TYPE_ERC712 = 1; + uint8 private constant SIG_TYPE_ERC1271 = 2; + + bytes4 internal constant ERC1271_MAGICVALUE = 0x1626ba7e; + + /** + * Check if a signature is valid. + * @param digest The digest to check. + * @param signature The signature to check. + * @return signer The detected signer address if valid, otherwise address(0). + * @dev An ERC721 signature is formatted `0x01`. + * @dev An ERC1271 signature is formatted `0x02`. + */ + function recoverSigner(bytes32 digest, bytes calldata signature) internal view returns (address signer) { + // Check first byte of signature for signature type + uint8 sigType = uint8(signature[0]); + if (sigType == SIG_TYPE_ERC712) { + // ERC712 + signer = digest.recoverCalldata(signature[1:]); + } else if (sigType == SIG_TYPE_ERC1271 && signature.length >= 21) { + // ERC1271 + assembly { + let word := calldataload(add(1, signature.offset)) + signer := shr(96, word) + } + try IERC1271Wallet(signer).isValidSignature(digest, signature[21:]) returns (bytes4 magicValue) { + if (magicValue != ERC1271_MAGICVALUE) { + signer = address(0); + } + } catch { + signer = address(0); + } + } + } +} diff --git a/test/_mocks/ERC1271Mock.sol b/test/_mocks/ERC1271Mock.sol new file mode 100644 index 0000000..ca9d410 --- /dev/null +++ b/test/_mocks/ERC1271Mock.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.19; + +import {IERC1271Wallet} from "@0xsequence/erc-1155/contracts/interfaces/IERC1271Wallet.sol"; + +contract ERC1271Mock is IERC1271Wallet { + mapping(bytes32 => bool) private _validSignatures; + + function setValidSignature(bytes32 signature) public { + _validSignatures[signature] = true; + } + + function isValidSignature(bytes calldata, bytes calldata signature) + external + view + override + returns (bytes4 magicValue) + { + bytes32 sigBytes32 = abi.decode(signature, (bytes32)); + if (_validSignatures[sigBytes32]) { + return 0x20c13b0b; + } else { + return 0x0; + } + } + + function isValidSignature(bytes32, bytes calldata signature) external view override returns (bytes4 magicValue) { + bytes32 sigBytes32 = abi.decode(signature, (bytes32)); + if (_validSignatures[sigBytes32]) { + return 0x1626ba7e; + } else { + return 0x0; + } + } +} diff --git a/test/payments/Payments.t.sol b/test/payments/Payments.t.sol index 88c7824..7fe97c9 100644 --- a/test/payments/Payments.t.sol +++ b/test/payments/Payments.t.sol @@ -10,12 +10,14 @@ import {ERC1155Mock} from "test/_mocks/ERC1155Mock.sol"; import {ERC20Mock} from "test/_mocks/ERC20Mock.sol"; import {ERC721Mock} from "test/_mocks/ERC721Mock.sol"; import {IGenericToken} from "test/_mocks/IGenericToken.sol"; +import {ERC1271Mock} from "test/_mocks/ERC1271Mock.sol"; contract PaymentsTest is Test, IPaymentsSignals { Payments public payments; address public owner; address public signer; uint256 public signerPk; + ERC1271Mock public signer1271; ERC20Mock public erc20; ERC721Mock public erc721; @@ -29,6 +31,8 @@ contract PaymentsTest is Test, IPaymentsSignals { erc20 = new ERC20Mock(address(this)); erc721 = new ERC721Mock(address(this), "baseURI"); erc1155 = new ERC1155Mock(address(this), "baseURI"); + + signer1271 = new ERC1271Mock(); } struct DetailsInput { @@ -68,7 +72,42 @@ contract PaymentsTest is Test, IPaymentsSignals { return (address(erc1155), tokenId, bound(amount, 1, type(uint128).max / 10)); } - function testMakePaymentSuccess(address caller, DetailsInput calldata input) + function _signPayment(IPaymentsFunctions.PaymentDetails memory details, bool isERC1271, bool isValid) + internal + returns (bytes memory signature) + { + bytes32 digest = payments.hashPaymentDetails(details); + return _signDigest(digest, isERC1271, isValid); + } + + function _signChainedCall(IPaymentsFunctions.ChainedCallDetails memory details, bool isERC1271, bool isValid) + internal + returns (bytes memory signature) + { + bytes32 digest = payments.hashChainedCallDetails(details); + return _signDigest(digest, isERC1271, isValid); + } + + function _signDigest(bytes32 digest, bool isERC1271, bool isValid) internal returns (bytes memory signature) { + if (isERC1271) { + vm.prank(owner); + payments.updateSigner(address(signer1271)); + + // Pretend digest is the signature + if (isValid) { + signer1271.setValidSignature(digest); + } + return abi.encodePacked(uint8(2), address(signer1271), digest); + } else { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, digest); + if (!isValid) { + v--; // Invalidate sig + } + return abi.encodePacked(uint8(1), r, s, v); + } + } + + function testMakePaymentSuccess(address caller, DetailsInput calldata input, bool isERC1271) public safeAddress(caller) safeAddress(input.paymentRecipient.recipient) @@ -98,9 +137,7 @@ contract PaymentsTest is Test, IPaymentsSignals { IGenericToken(tokenAddr).approve(caller, address(payments), tokenId, amount); // Sign it - bytes32 messageHash = payments.hashPaymentDetails(details); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, messageHash); - bytes memory sig = abi.encodePacked(r, s, v); + bytes memory sig = _signPayment(details, isERC1271, true); // Send it vm.expectEmit(true, true, true, true, address(payments)); @@ -116,7 +153,7 @@ contract PaymentsTest is Test, IPaymentsSignals { payments.makePayment(details, sig); } - function testMakePaymentSuccessChainedCall(address caller, DetailsInput calldata input) + function testMakePaymentSuccessChainedCall(address caller, DetailsInput calldata input, bool isERC1271) public safeAddress(caller) safeAddress(input.paymentRecipient.recipient) @@ -161,9 +198,7 @@ contract PaymentsTest is Test, IPaymentsSignals { IGenericToken(tokenAddr).approve(caller, address(payments), tokenId, amount); // Sign it - bytes32 messageHash = payments.hashPaymentDetails(details); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, messageHash); - bytes memory sig = abi.encodePacked(r, s, v); + bytes memory sig = _signPayment(details, isERC1271, true); // Send it vm.expectEmit(true, true, true, true, address(payments)); @@ -176,12 +211,12 @@ contract PaymentsTest is Test, IPaymentsSignals { assertEq(IGenericToken(chainedTokenAddr).balanceOf(input.productRecipient, chainedTokenId), chainedAmount); } - function testMakePaymentSuccessMultiplePaymentRecips(address caller, DetailsInput calldata input, address recip2) - public - safeAddress(caller) - safeAddress(input.paymentRecipient.recipient) - safeAddress(recip2) - { + function testMakePaymentSuccessMultiplePaymentRecips( + address caller, + DetailsInput calldata input, + address recip2, + bool isERC1271 + ) public safeAddress(caller) safeAddress(input.paymentRecipient.recipient) safeAddress(recip2) { vm.assume(input.paymentRecipient.recipient != recip2); IPaymentsFunctions.TokenType tokenType = _toTokenType(input.tokenType); vm.assume(tokenType != IPaymentsFunctions.TokenType.ERC721); // ERC-721 not supported for multi payments @@ -212,9 +247,7 @@ contract PaymentsTest is Test, IPaymentsSignals { IGenericToken(tokenAddr).approve(caller, address(payments), tokenId, amount * 2); // Sign it - bytes32 messageHash = payments.hashPaymentDetails(details); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, messageHash); - bytes memory sig = abi.encodePacked(r, s, v); + bytes memory sig = _signPayment(details, isERC1271, true); // Send it vm.expectEmit(true, true, true, true, address(payments)); @@ -226,9 +259,7 @@ contract PaymentsTest is Test, IPaymentsSignals { assertEq(IGenericToken(tokenAddr).balanceOf(recip2, tokenId), amount); } - function testMakePaymentInvalidSignature(address caller, DetailsInput calldata input, bytes memory signature) - public - { + function testMakePaymentInvalidSignature(address caller, DetailsInput calldata input, bool isERC1271) public { uint64 expiration = uint64(_bound(input.expiration, block.timestamp, type(uint64).max)); IPaymentsFunctions.TokenType tokenType = _toTokenType(input.tokenType); (address tokenAddr, uint256 tokenId, uint256 amount) = @@ -249,13 +280,16 @@ contract PaymentsTest is Test, IPaymentsSignals { IPaymentsFunctions.ChainedCallDetails(address(0), "") ); + // Invalid sign it + bytes memory sig = _signPayment(details, isERC1271, false); + // Send it vm.expectRevert(InvalidSignature.selector); vm.prank(caller); - payments.makePayment(details, signature); + payments.makePayment(details, sig); } - function testMakePaymentExpired(address caller, DetailsInput calldata input, uint64 blockTimestamp) + function testMakePaymentExpired(address caller, DetailsInput calldata input, uint64 blockTimestamp, bool isERC1271) public safeAddress(caller) safeAddress(input.paymentRecipient.recipient) @@ -287,9 +321,7 @@ contract PaymentsTest is Test, IPaymentsSignals { IGenericToken(tokenAddr).approve(caller, address(payments), tokenId, amount); // Sign it - bytes32 messageHash = payments.hashPaymentDetails(details); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, messageHash); - bytes memory sig = abi.encodePacked(r, s, v); + bytes memory sig = _signPayment(details, isERC1271, true); // Send it vm.expectRevert(PaymentExpired.selector); @@ -297,7 +329,7 @@ contract PaymentsTest is Test, IPaymentsSignals { payments.makePayment(details, sig); } - function testMakePaymentInvalidPayment(address caller, DetailsInput calldata input) + function testMakePaymentInvalidPayment(address caller, DetailsInput calldata input, bool isERC1271) public safeAddress(caller) safeAddress(input.paymentRecipient.recipient) @@ -325,9 +357,7 @@ contract PaymentsTest is Test, IPaymentsSignals { // Do not mint required tokens // Sign it - bytes32 messageHash = payments.hashPaymentDetails(details); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, messageHash); - bytes memory sig = abi.encodePacked(r, s, v); + bytes memory sig = _signPayment(details, isERC1271, true); // Send it vm.expectRevert(); @@ -335,11 +365,12 @@ contract PaymentsTest is Test, IPaymentsSignals { payments.makePayment(details, sig); } - function testMakePaymentInvalidTokenSettingsERC20(address caller, DetailsInput calldata input, uint256 tokenId) - public - safeAddress(caller) - safeAddress(input.paymentRecipient.recipient) - { + function testMakePaymentInvalidTokenSettingsERC20( + address caller, + DetailsInput calldata input, + uint256 tokenId, + bool isERC1271 + ) public safeAddress(caller) safeAddress(input.paymentRecipient.recipient) { tokenId = _bound(tokenId, 1, type(uint256).max); // Non-zero uint64 expiration = uint64(_bound(input.expiration, block.timestamp, type(uint64).max)); @@ -362,9 +393,7 @@ contract PaymentsTest is Test, IPaymentsSignals { ); // Sign it - bytes32 messageHash = payments.hashPaymentDetails(details); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, messageHash); - bytes memory sig = abi.encodePacked(r, s, v); + bytes memory sig = _signPayment(details, isERC1271, true); // Send it vm.expectRevert(InvalidTokenTransfer.selector); @@ -372,7 +401,7 @@ contract PaymentsTest is Test, IPaymentsSignals { payments.makePayment(details, sig); } - function testMakePaymentInvalidTokenSettingsERC721(address caller, DetailsInput calldata input) + function testMakePaymentInvalidTokenSettingsERC721(address caller, DetailsInput calldata input, bool isERC1271) public safeAddress(caller) safeAddress(input.paymentRecipient.recipient) @@ -398,9 +427,7 @@ contract PaymentsTest is Test, IPaymentsSignals { ); // Sign it - bytes32 messageHash = payments.hashPaymentDetails(details); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, messageHash); - bytes memory sig = abi.encodePacked(r, s, v); + bytes memory sig = _signPayment(details, isERC1271, true); // Send it vm.expectRevert(InvalidTokenTransfer.selector); @@ -408,12 +435,12 @@ contract PaymentsTest is Test, IPaymentsSignals { payments.makePayment(details, sig); } - function testMakePaymentFailedChainedCall(address caller, DetailsInput calldata input, bytes memory chainedCallData) - public - safeAddress(caller) - safeAddress(input.paymentRecipient.recipient) - safeAddress(input.productRecipient) - { + function testMakePaymentFailedChainedCall( + address caller, + DetailsInput calldata input, + bytes memory chainedCallData, + bool isERC1271 + ) public safeAddress(caller) safeAddress(input.paymentRecipient.recipient) safeAddress(input.productRecipient) { // Check the call will fail (bool success,) = address(payments).call(chainedCallData); vm.assume(!success); @@ -443,9 +470,7 @@ contract PaymentsTest is Test, IPaymentsSignals { IGenericToken(tokenAddr).approve(caller, address(payments), tokenId, amount); // Sign it - bytes32 messageHash = payments.hashPaymentDetails(details); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, messageHash); - bytes memory sig = abi.encodePacked(r, s, v); + bytes memory sig = _signPayment(details, isERC1271, true); // Send it vm.expectRevert(ChainedCallFailed.selector); @@ -455,10 +480,13 @@ contract PaymentsTest is Test, IPaymentsSignals { // Chained call - function testPerformChainedCallSuccess(uint8 tokenTypeInt, uint256 tokenId, uint256 amount, address recipient) - public - safeAddress(recipient) - { + function testPerformChainedCallSuccess( + uint8 tokenTypeInt, + uint256 tokenId, + uint256 amount, + address recipient, + bool isERC1271 + ) public safeAddress(recipient) { IPaymentsFunctions.TokenType tokenType = _toTokenType(tokenTypeInt); address tokenAddr; (tokenAddr, tokenId, amount) = _validTokenParams(tokenType, tokenId, amount); @@ -468,9 +496,7 @@ contract PaymentsTest is Test, IPaymentsSignals { IPaymentsFunctions.ChainedCallDetails(tokenAddr, callData); // Sign it - bytes32 messageHash = payments.hashChainedCallDetails(chainedCallDetails); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, messageHash); - bytes memory sig = abi.encodePacked(r, s, v); + bytes memory sig = _signChainedCall(chainedCallDetails, isERC1271, true); // Send it vm.prank(signer); @@ -485,7 +511,7 @@ contract PaymentsTest is Test, IPaymentsSignals { uint256 tokenId, uint256 amount, address recipient, - bytes calldata sig + bool isERC1271 ) public safeAddress(recipient) { vm.assume(caller != signer); @@ -497,13 +523,16 @@ contract PaymentsTest is Test, IPaymentsSignals { IPaymentsFunctions.ChainedCallDetails memory chainedCallDetails = IPaymentsFunctions.ChainedCallDetails(tokenAddr, callData); + // Fake sign it + bytes memory sig = _signChainedCall(chainedCallDetails, isERC1271, false); + // Send it vm.expectRevert(InvalidSignature.selector); vm.prank(caller); payments.performChainedCall(chainedCallDetails, sig); } - function testPerformChainedCallInvalidCall(bytes calldata chainedCallData) public { + function testPerformChainedCallInvalidCall(bytes calldata chainedCallData, bool isERC1271) public { IPaymentsFunctions.ChainedCallDetails memory chainedCallDetails = IPaymentsFunctions.ChainedCallDetails(address(this), chainedCallData); // Check the call will fail @@ -511,9 +540,7 @@ contract PaymentsTest is Test, IPaymentsSignals { vm.assume(!success); // Sign it - bytes32 messageHash = payments.hashChainedCallDetails(chainedCallDetails); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, messageHash); - bytes memory sig = abi.encodePacked(r, s, v); + bytes memory sig = _signChainedCall(chainedCallDetails, isERC1271, true); vm.expectRevert(ChainedCallFailed.selector); vm.prank(signer);