@zoralabs/comments-contracts 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +11 -0
- package/.turbo/turbo-build.log +60 -0
- package/LICENSE +21 -0
- package/README.md +70 -0
- package/_imagine/Enjoy.sol +41 -0
- package/abis/AccessControlUpgradeable.json +250 -0
- package/abis/Address.json +29 -0
- package/abis/Comments.json +62 -0
- package/abis/CommentsDeployerBase.json +15 -0
- package/abis/CommentsImpl.json +1750 -0
- package/abis/CommentsPermitTest.json +847 -0
- package/abis/CommentsTest.json +986 -0
- package/abis/CommentsTestBase.json +577 -0
- package/abis/Comments_mintAndCommentTest.json +690 -0
- package/abis/ContextUpgradeable.json +25 -0
- package/abis/ContractVersionBase.json +15 -0
- package/abis/Create2.json +28 -0
- package/abis/DeployImpl.json +22 -0
- package/abis/DeployNonDeterministic.json +22 -0
- package/abis/DeployScript.json +22 -0
- package/abis/DeterministicDeployerAndCaller.json +315 -0
- package/abis/DeterministicUUPSProxyDeployer.json +167 -0
- package/abis/ECDSA.json +29 -0
- package/abis/EIP712.json +67 -0
- package/abis/EIP712UpgradeableWithChainId.json +25 -0
- package/abis/ERC1155.json +416 -0
- package/abis/ERC1155Holder.json +99 -0
- package/abis/ERC165.json +21 -0
- package/abis/ERC165Upgradeable.json +44 -0
- package/abis/ERC1967Proxy.json +67 -0
- package/abis/ERC1967Utils.json +85 -0
- package/abis/GenerateDeterministicParams.json +22 -0
- package/abis/IAccessControl.json +195 -0
- package/abis/IBeacon.json +15 -0
- package/abis/IComments.json +654 -0
- package/abis/IContractMetadata.json +28 -0
- package/abis/IERC1155.json +295 -0
- package/abis/IERC1155Errors.json +104 -0
- package/abis/IERC1155MetadataURI.json +314 -0
- package/abis/IERC1155Receiver.json +99 -0
- package/abis/IERC1271.json +26 -0
- package/abis/IERC165.json +21 -0
- package/abis/IERC1822Proxiable.json +15 -0
- package/abis/IERC20.json +224 -0
- package/abis/IERC20Errors.json +88 -0
- package/abis/IERC5267.json +51 -0
- package/abis/IERC721.json +287 -0
- package/abis/IERC721Enumerable.json +343 -0
- package/abis/IERC721Errors.json +105 -0
- package/abis/IERC721Metadata.json +332 -0
- package/abis/IERC721TokenReceiver.json +36 -0
- package/abis/IHasContractName.json +15 -0
- package/abis/IImmutableCreate2Factory.json +93 -0
- package/abis/IMulticall3.json +440 -0
- package/abis/IProtocolRewards.json +342 -0
- package/abis/ISafe.json +15 -0
- package/abis/ISymbol.json +15 -0
- package/abis/IVersionedContract.json +15 -0
- package/abis/IZoraCreator1155.json +343 -0
- package/abis/ImmutableCreate2FactoryUtils.json +15 -0
- package/abis/Initializable.json +25 -0
- package/abis/LibString.json +7 -0
- package/abis/Math.json +7 -0
- package/abis/Mock1155.json +547 -0
- package/abis/MockERC20.json +322 -0
- package/abis/MockERC721.json +350 -0
- package/abis/MockMinter.json +64 -0
- package/abis/OwnableUpgradeable.json +99 -0
- package/abis/ProtocolRewards.json +494 -0
- package/abis/Proxy.json +6 -0
- package/abis/ProxyDeployerScript.json +15 -0
- package/abis/ProxyShim.json +112 -0
- package/abis/Script.json +15 -0
- package/abis/ShortStrings.json +18 -0
- package/abis/StdAssertions.json +379 -0
- package/abis/StdInvariant.json +180 -0
- package/abis/Strings.json +18 -0
- package/abis/Test.json +570 -0
- package/abis/UUPSUpgradeable.json +130 -0
- package/abis/UnorderedNoncesUpgradeable.json +42 -0
- package/abis/Vm.json +8627 -0
- package/abis/VmSafe.json +7297 -0
- package/abis/stdError.json +119 -0
- package/abis/stdStorageSafe.json +52 -0
- package/addresses/999999999.json +4 -0
- package/deterministicConfig/comments.json +8 -0
- package/dist/index.cjs +935 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +908 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/wagmiGenerated.d.ts +1354 -0
- package/dist/wagmiGenerated.d.ts.map +1 -0
- package/foundry.toml +24 -0
- package/package/index.ts +4 -0
- package/package/types.ts +5 -0
- package/package/wagmiGenerated.ts +907 -0
- package/package.json +62 -0
- package/remappings.txt +8 -0
- package/script/CommentsDeployerBase.sol +60 -0
- package/script/Deploy.s.sol +66 -0
- package/script/DeployImpl.s.sol +26 -0
- package/script/DeployNonDeterministic.s.sol +43 -0
- package/script/GenerateDeterministicParams.s.sol +55 -0
- package/script/bundle-abis.ts +109 -0
- package/script/storage-check.sh +57 -0
- package/script/update-contract-version.ts +63 -0
- package/scripts/abis.ts +3 -0
- package/scripts/backfillComments.ts +176 -0
- package/scripts/generateCommentsTestData.ts +247 -0
- package/scripts/getCommentsAddresses.ts +10 -0
- package/scripts/queries.ts +73 -0
- package/scripts/queryAndSaveComments.ts +48 -0
- package/scripts/queryQuantityOfComments.ts +53 -0
- package/scripts/signDeployAndCall.ts +51 -0
- package/scripts/turnkey.ts +36 -0
- package/scripts/utils.ts +127 -0
- package/scripts/writeComments.ts +198 -0
- package/slither.config.json +7 -0
- package/src/CommentsImpl.sol +552 -0
- package/src/deployments/CommentsDeployment.sol +14 -0
- package/src/interfaces/IComments.sol +156 -0
- package/src/interfaces/IZoraCreator1155.sol +12 -0
- package/src/proxy/Comments.sol +43 -0
- package/src/utils/EIP712UpgradeableWithChainId.sol +36 -0
- package/src/version/ContractVersionBase.sol +14 -0
- package/test/Comments.t.sol +482 -0
- package/test/CommentsTestBase.sol +86 -0
- package/test/Comments_mintAndComment.t.sol +101 -0
- package/test/Comments_permit.t.sol +397 -0
- package/test/mocks/Mock1155.sol +50 -0
- package/test/mocks/MockMinter.sol +29 -0
- package/test/mocks/ProtocolRewards.sol +1497 -0
- package/tsconfig.build.json +10 -0
- package/tsconfig.json +9 -0
- package/tsup.config.ts +11 -0
- package/wagmi.config.ts +14 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
import "forge-std/Test.sol";
|
|
5
|
+
|
|
6
|
+
import {CommentsImpl} from "../src/CommentsImpl.sol";
|
|
7
|
+
import {Comments} from "../src/proxy/Comments.sol";
|
|
8
|
+
import {IComments} from "../src/interfaces/IComments.sol";
|
|
9
|
+
import {Mock1155} from "./mocks/Mock1155.sol";
|
|
10
|
+
import {IProtocolRewards} from "@zoralabs/protocol-rewards/src/interfaces/IProtocolRewards.sol";
|
|
11
|
+
import {ProtocolRewards} from "./mocks/ProtocolRewards.sol";
|
|
12
|
+
import {CommentsTestBase} from "./CommentsTestBase.sol";
|
|
13
|
+
import {UnorderedNoncesUpgradeable} from "@zoralabs/shared-contracts/utils/UnorderedNoncesUpgradeable.sol";
|
|
14
|
+
|
|
15
|
+
contract CommentsPermitTest is CommentsTestBase {
|
|
16
|
+
function testPermitComment() public {
|
|
17
|
+
IComments.PermitComment memory permitComment = _createPermitComment(collectorWithToken, "test comment", 3);
|
|
18
|
+
bytes memory signature = _signPermitComment(permitComment, collectorWithTokenPrivateKey);
|
|
19
|
+
|
|
20
|
+
IComments.CommentIdentifier memory expectedCommentIdentifier = _expectedCommentIdentifier(
|
|
21
|
+
permitComment.contractAddress,
|
|
22
|
+
permitComment.tokenId,
|
|
23
|
+
permitComment.commenter
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
_setupTokenAndSparks(permitComment);
|
|
27
|
+
|
|
28
|
+
// any account can execute the permit comment on behalf of the collectorWithToken, but they must have enough eth to do so.
|
|
29
|
+
address executor = makeAddr("executor");
|
|
30
|
+
vm.deal(executor, permitComment.sparksQuantity * SPARKS_VALUE);
|
|
31
|
+
|
|
32
|
+
vm.expectEmit(true, true, true, true);
|
|
33
|
+
emit IComments.Commented(
|
|
34
|
+
comments.hashCommentIdentifier(expectedCommentIdentifier),
|
|
35
|
+
expectedCommentIdentifier,
|
|
36
|
+
bytes32(0),
|
|
37
|
+
permitComment.replyTo,
|
|
38
|
+
permitComment.sparksQuantity,
|
|
39
|
+
permitComment.text,
|
|
40
|
+
block.timestamp,
|
|
41
|
+
permitComment.referrer
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
_executePermitComment(executor, permitComment, signature);
|
|
45
|
+
|
|
46
|
+
_assertCommentExists(expectedCommentIdentifier);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function testPermitComment_NonceUsedTwice() public {
|
|
50
|
+
IComments.PermitComment memory permitComment = _createPermitComment(collectorWithToken, "test comment", 3);
|
|
51
|
+
bytes memory signature = _signPermitComment(permitComment, collectorWithTokenPrivateKey);
|
|
52
|
+
|
|
53
|
+
_setupTokenAndSparks(permitComment);
|
|
54
|
+
|
|
55
|
+
// First comment should succeed
|
|
56
|
+
vm.deal(collectorWithToken, 10 ether);
|
|
57
|
+
_executePermitComment(collectorWithToken, permitComment, signature);
|
|
58
|
+
|
|
59
|
+
// Second comment with same nonce should fail
|
|
60
|
+
vm.expectRevert(abi.encodeWithSelector(UnorderedNoncesUpgradeable.InvalidAccountNonce.selector, collectorWithToken, permitComment.nonce));
|
|
61
|
+
_executePermitComment(collectorWithToken, permitComment, signature);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function testPermitComment_DeadlineExpired() public {
|
|
65
|
+
IComments.PermitComment memory permitComment = _createPermitComment(collectorWithToken, "test comment", 3);
|
|
66
|
+
bytes memory signature = _signPermitComment(permitComment, collectorWithTokenPrivateKey);
|
|
67
|
+
|
|
68
|
+
_setupTokenAndSparks(permitComment);
|
|
69
|
+
|
|
70
|
+
// Warp time to after the deadline
|
|
71
|
+
vm.warp(permitComment.deadline + 1);
|
|
72
|
+
|
|
73
|
+
address executor = makeAddr("executor");
|
|
74
|
+
vm.deal(executor, permitComment.sparksQuantity * SPARKS_VALUE);
|
|
75
|
+
vm.expectRevert(abi.encodeWithSelector(IComments.ERC2612ExpiredSignature.selector, permitComment.deadline));
|
|
76
|
+
_executePermitComment(executor, permitComment, signature);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function testPermitComment_CommenterDoesntMatchSigner() public {
|
|
80
|
+
address wrongSigner;
|
|
81
|
+
uint256 wrongSignerPrivateKey;
|
|
82
|
+
(wrongSigner, wrongSignerPrivateKey) = makeAddrAndKey("wrongSigner");
|
|
83
|
+
|
|
84
|
+
IComments.PermitComment memory permitComment = _createPermitComment(collectorWithToken, "test comment", 3);
|
|
85
|
+
bytes memory wrongSignature = _signPermitComment(permitComment, wrongSignerPrivateKey);
|
|
86
|
+
|
|
87
|
+
_setupTokenAndSparks(permitComment);
|
|
88
|
+
|
|
89
|
+
vm.expectRevert(IComments.InvalidSignature.selector);
|
|
90
|
+
_executePermitComment(collectorWithToken, permitComment, wrongSignature);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function testPermitComment_ZeroSparks() public {
|
|
94
|
+
IComments.PermitComment memory permitComment = _createPermitComment(collectorWithToken, "test comment", 0);
|
|
95
|
+
bytes memory signature = _signPermitComment(permitComment, collectorWithTokenPrivateKey);
|
|
96
|
+
|
|
97
|
+
_setupTokenAndSparks(permitComment);
|
|
98
|
+
|
|
99
|
+
vm.expectRevert(IComments.MustSendAtLeastOneSpark.selector);
|
|
100
|
+
_executePermitComment(collectorWithToken, permitComment, signature);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function testPermitComment_Not1155Holder() public {
|
|
104
|
+
IComments.PermitComment memory permitComment = _createPermitComment(collectorWithToken, "test comment", 3);
|
|
105
|
+
bytes memory signature = _signPermitComment(permitComment, collectorWithTokenPrivateKey);
|
|
106
|
+
|
|
107
|
+
address executor = makeAddr("executor");
|
|
108
|
+
vm.deal(executor, permitComment.sparksQuantity * SPARKS_VALUE);
|
|
109
|
+
vm.expectRevert(IComments.NotTokenHolderOrAdmin.selector);
|
|
110
|
+
_executePermitComment(executor, permitComment, signature);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function testPermitSparkCommentSparksComment() public {
|
|
114
|
+
IComments.PermitSparkComment memory permitSparkComment = _postCommentAndCreatePermitSparkComment(sparker, 3);
|
|
115
|
+
bytes memory signature = _signPermitSparkComment(permitSparkComment, sparkerPrivateKey);
|
|
116
|
+
|
|
117
|
+
_setupSparkComment(permitSparkComment);
|
|
118
|
+
|
|
119
|
+
address executor = makeAddr("executor");
|
|
120
|
+
vm.deal(executor, permitSparkComment.sparksQuantity * SPARKS_VALUE);
|
|
121
|
+
|
|
122
|
+
bytes32 commentId = comments.hashCommentIdentifier(permitSparkComment.comment);
|
|
123
|
+
|
|
124
|
+
uint256 beforeSparksCount = comments.commentSparksQuantity(commentId);
|
|
125
|
+
|
|
126
|
+
vm.expectEmit(true, true, true, true);
|
|
127
|
+
emit IComments.SparkedComment(commentId, permitSparkComment.comment, permitSparkComment.sparksQuantity, sparker, block.timestamp);
|
|
128
|
+
|
|
129
|
+
_executePermitSparkComment(executor, permitSparkComment, signature);
|
|
130
|
+
|
|
131
|
+
uint256 afterSparksCount = comments.commentSparksQuantity(commentId);
|
|
132
|
+
assertEq(afterSparksCount, beforeSparksCount + permitSparkComment.sparksQuantity);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function testPermitSparkComment_NonceUsedTwice() public {
|
|
136
|
+
IComments.PermitSparkComment memory permitSparkComment = _postCommentAndCreatePermitSparkComment(sparker, 3);
|
|
137
|
+
bytes memory signature = _signPermitSparkComment(permitSparkComment, sparkerPrivateKey);
|
|
138
|
+
|
|
139
|
+
_setupSparkComment(permitSparkComment);
|
|
140
|
+
|
|
141
|
+
// First spark should succeed
|
|
142
|
+
vm.deal(sparker, 10 ether);
|
|
143
|
+
_executePermitSparkComment(sparker, permitSparkComment, signature);
|
|
144
|
+
|
|
145
|
+
// Second spark with same nonce should fail
|
|
146
|
+
vm.expectRevert(abi.encodeWithSelector(UnorderedNoncesUpgradeable.InvalidAccountNonce.selector, sparker, permitSparkComment.nonce));
|
|
147
|
+
_executePermitSparkComment(sparker, permitSparkComment, signature);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function testPermitSparkComment_DeadlineExpired() public {
|
|
151
|
+
IComments.PermitSparkComment memory permitSparkComment = _postCommentAndCreatePermitSparkComment(sparker, 3);
|
|
152
|
+
bytes memory signature = _signPermitSparkComment(permitSparkComment, sparkerPrivateKey);
|
|
153
|
+
|
|
154
|
+
_setupSparkComment(permitSparkComment);
|
|
155
|
+
|
|
156
|
+
// Warp time to after the deadline
|
|
157
|
+
vm.warp(permitSparkComment.deadline + 1);
|
|
158
|
+
|
|
159
|
+
address executor = makeAddr("executor");
|
|
160
|
+
vm.deal(executor, permitSparkComment.sparksQuantity * SPARKS_VALUE);
|
|
161
|
+
vm.expectRevert(abi.encodeWithSelector(IComments.ERC2612ExpiredSignature.selector, permitSparkComment.deadline));
|
|
162
|
+
_executePermitSparkComment(executor, permitSparkComment, signature);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function testPermitSparkComment_CommenterDoesntMatchSigner() public {
|
|
166
|
+
address wrongSigner;
|
|
167
|
+
uint256 wrongSignerPrivateKey;
|
|
168
|
+
(wrongSigner, wrongSignerPrivateKey) = makeAddrAndKey("wrongSigner");
|
|
169
|
+
|
|
170
|
+
IComments.PermitSparkComment memory permitSparkComment = _postCommentAndCreatePermitSparkComment(sparker, 3);
|
|
171
|
+
bytes memory wrongSignature = _signPermitSparkComment(permitSparkComment, wrongSignerPrivateKey);
|
|
172
|
+
|
|
173
|
+
_setupSparkComment(permitSparkComment);
|
|
174
|
+
|
|
175
|
+
vm.expectRevert(IComments.InvalidSignature.selector);
|
|
176
|
+
_executePermitSparkComment(makeAddr("executor"), permitSparkComment, wrongSignature);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function testPermitSparkComment_ZeroSparks() public {
|
|
180
|
+
IComments.PermitSparkComment memory permitSparkComment = _postCommentAndCreatePermitSparkComment(sparker, 0);
|
|
181
|
+
bytes memory signature = _signPermitSparkComment(permitSparkComment, sparkerPrivateKey);
|
|
182
|
+
|
|
183
|
+
_setupSparkComment(permitSparkComment);
|
|
184
|
+
|
|
185
|
+
vm.expectRevert(IComments.MustSendAtLeastOneSpark.selector);
|
|
186
|
+
_executePermitSparkComment(collectorWithToken, permitSparkComment, signature);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function testPermitSparkComment_IncorrectETHAmount() public {
|
|
190
|
+
IComments.PermitSparkComment memory permitSparkComment = _postCommentAndCreatePermitSparkComment(sparker, 3);
|
|
191
|
+
bytes memory signature = _signPermitSparkComment(permitSparkComment, sparkerPrivateKey);
|
|
192
|
+
|
|
193
|
+
_setupSparkComment(permitSparkComment);
|
|
194
|
+
|
|
195
|
+
address executor = makeAddr("executor");
|
|
196
|
+
uint256 incorrectValue = (permitSparkComment.sparksQuantity * SPARKS_VALUE) + 1 wei;
|
|
197
|
+
vm.deal(executor, incorrectValue);
|
|
198
|
+
|
|
199
|
+
vm.expectRevert(
|
|
200
|
+
abi.encodeWithSelector(IComments.IncorrectETHAmountForSparks.selector, incorrectValue, permitSparkComment.sparksQuantity * SPARKS_VALUE)
|
|
201
|
+
);
|
|
202
|
+
vm.prank(executor);
|
|
203
|
+
comments.permitSparkComment{value: incorrectValue}(permitSparkComment, signature);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function testPermitCommentCrossChain() public {
|
|
207
|
+
uint256 sourceChainId = 1; // Ethereum mainnet
|
|
208
|
+
uint256 destinationChainId = block.chainid;
|
|
209
|
+
|
|
210
|
+
IComments.PermitComment memory permitComment = _createPermitComment(collectorWithToken, "cross-chain comment", 3);
|
|
211
|
+
permitComment.sourceChainId = sourceChainId;
|
|
212
|
+
permitComment.destinationChainId = destinationChainId;
|
|
213
|
+
|
|
214
|
+
IComments.CommentIdentifier memory expectedCommentIdentifier = _expectedCommentIdentifier(
|
|
215
|
+
permitComment.contractAddress,
|
|
216
|
+
permitComment.tokenId,
|
|
217
|
+
permitComment.commenter
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
bytes memory signature = _signPermitComment(permitComment, collectorWithTokenPrivateKey);
|
|
221
|
+
|
|
222
|
+
_setupTokenAndSparks(permitComment);
|
|
223
|
+
|
|
224
|
+
address executor = makeAddr("executor");
|
|
225
|
+
vm.deal(executor, permitComment.sparksQuantity * SPARKS_VALUE);
|
|
226
|
+
|
|
227
|
+
vm.expectEmit(true, true, true, true);
|
|
228
|
+
emit IComments.Commented(
|
|
229
|
+
comments.hashCommentIdentifier(expectedCommentIdentifier),
|
|
230
|
+
expectedCommentIdentifier,
|
|
231
|
+
bytes32(0),
|
|
232
|
+
permitComment.replyTo,
|
|
233
|
+
permitComment.sparksQuantity,
|
|
234
|
+
permitComment.text,
|
|
235
|
+
block.timestamp,
|
|
236
|
+
permitComment.referrer
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
_executePermitComment(executor, permitComment, signature);
|
|
240
|
+
|
|
241
|
+
_assertCommentExists(expectedCommentIdentifier);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function testPermitCommentCrossChainInvalidDestination() public {
|
|
245
|
+
uint256 sourceChainId = 1; // Ethereum mainnet
|
|
246
|
+
uint256 invalidDestinationChainId = 42; // Some other chain ID
|
|
247
|
+
|
|
248
|
+
IComments.PermitComment memory permitComment = _createPermitComment(collectorWithToken, "invalid cross-chain comment", 3);
|
|
249
|
+
permitComment.sourceChainId = sourceChainId;
|
|
250
|
+
permitComment.destinationChainId = invalidDestinationChainId;
|
|
251
|
+
|
|
252
|
+
bytes memory signature = _signPermitComment(permitComment, collectorWithTokenPrivateKey);
|
|
253
|
+
|
|
254
|
+
_setupTokenAndSparks(permitComment);
|
|
255
|
+
|
|
256
|
+
address executor = makeAddr("executor");
|
|
257
|
+
vm.deal(executor, permitComment.sparksQuantity * SPARKS_VALUE);
|
|
258
|
+
|
|
259
|
+
vm.expectRevert(abi.encodeWithSelector(IComments.IncorrectDestinationChain.selector, invalidDestinationChainId));
|
|
260
|
+
_executePermitComment(executor, permitComment, signature);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function testPermitSparkCommentCrossChain() public {
|
|
264
|
+
uint256 sourceChainId = 1; // Ethereum mainnet
|
|
265
|
+
uint256 destinationChainId = block.chainid;
|
|
266
|
+
|
|
267
|
+
IComments.PermitSparkComment memory permitSparkComment = _postCommentAndCreatePermitSparkComment(sparker, 3);
|
|
268
|
+
permitSparkComment.sourceChainId = sourceChainId;
|
|
269
|
+
permitSparkComment.destinationChainId = destinationChainId;
|
|
270
|
+
|
|
271
|
+
bytes memory signature = _signPermitSparkComment(permitSparkComment, sparkerPrivateKey);
|
|
272
|
+
|
|
273
|
+
_setupSparkComment(permitSparkComment);
|
|
274
|
+
|
|
275
|
+
address executor = makeAddr("executor");
|
|
276
|
+
vm.deal(executor, permitSparkComment.sparksQuantity * SPARKS_VALUE);
|
|
277
|
+
|
|
278
|
+
bytes32 commentId = comments.hashCommentIdentifier(permitSparkComment.comment);
|
|
279
|
+
|
|
280
|
+
uint256 beforeSparksCount = comments.commentSparksQuantity(commentId);
|
|
281
|
+
|
|
282
|
+
vm.expectEmit(true, true, true, true);
|
|
283
|
+
emit IComments.SparkedComment(commentId, permitSparkComment.comment, permitSparkComment.sparksQuantity, sparker, block.timestamp);
|
|
284
|
+
|
|
285
|
+
_executePermitSparkComment(executor, permitSparkComment, signature);
|
|
286
|
+
|
|
287
|
+
uint256 afterSparksCount = comments.commentSparksQuantity(commentId);
|
|
288
|
+
assertEq(afterSparksCount, beforeSparksCount + permitSparkComment.sparksQuantity);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function testPermitSparkCommentCrossChainInvalidDestination() public {
|
|
292
|
+
uint256 sourceChainId = 1; // Ethereum mainnet
|
|
293
|
+
uint256 invalidDestinationChainId = 42; // Some other chain ID
|
|
294
|
+
|
|
295
|
+
IComments.PermitSparkComment memory permitSparkComment = _postCommentAndCreatePermitSparkComment(sparker, 3);
|
|
296
|
+
permitSparkComment.sourceChainId = sourceChainId;
|
|
297
|
+
permitSparkComment.destinationChainId = invalidDestinationChainId;
|
|
298
|
+
|
|
299
|
+
bytes memory signature = _signPermitSparkComment(permitSparkComment, sparkerPrivateKey);
|
|
300
|
+
|
|
301
|
+
_setupSparkComment(permitSparkComment);
|
|
302
|
+
|
|
303
|
+
address executor = makeAddr("executor");
|
|
304
|
+
vm.deal(executor, permitSparkComment.sparksQuantity * SPARKS_VALUE);
|
|
305
|
+
|
|
306
|
+
vm.expectRevert(abi.encodeWithSelector(IComments.IncorrectDestinationChain.selector, invalidDestinationChainId));
|
|
307
|
+
_executePermitSparkComment(executor, permitSparkComment, signature);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function _postCommentAndCreatePermitSparkComment(address _sparker, uint64 sparksQuantity) internal returns (IComments.PermitSparkComment memory) {
|
|
311
|
+
IComments.CommentIdentifier memory emptyReplyTo;
|
|
312
|
+
address commenter = makeAddr("commenter_b");
|
|
313
|
+
IComments.CommentIdentifier memory commentIdentifier = _mockComment(commenter, emptyReplyTo);
|
|
314
|
+
|
|
315
|
+
return _createPermitSparkComment(commentIdentifier, _sparker, sparksQuantity, block.chainid, block.chainid);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Helper functions
|
|
319
|
+
function _createPermitSparkComment(
|
|
320
|
+
IComments.CommentIdentifier memory commentIdentifier,
|
|
321
|
+
address _sparker,
|
|
322
|
+
uint64 sparksQuantity,
|
|
323
|
+
uint256 sourceChainId,
|
|
324
|
+
uint256 destinationChainId
|
|
325
|
+
) internal returns (IComments.PermitSparkComment memory) {
|
|
326
|
+
return
|
|
327
|
+
IComments.PermitSparkComment({
|
|
328
|
+
comment: commentIdentifier,
|
|
329
|
+
sparker: _sparker,
|
|
330
|
+
sparksQuantity: sparksQuantity,
|
|
331
|
+
deadline: block.timestamp + 100,
|
|
332
|
+
nonce: bytes32("1"),
|
|
333
|
+
referrer: makeAddr("referrer"),
|
|
334
|
+
sourceChainId: sourceChainId,
|
|
335
|
+
destinationChainId: destinationChainId
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function _signPermitSparkComment(IComments.PermitSparkComment memory permitSparkComment, uint256 privateKey) internal view returns (bytes memory) {
|
|
340
|
+
bytes32 digest = comments.hashPermitSparkComment(permitSparkComment);
|
|
341
|
+
return _sign(privateKey, digest);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function _setupSparkComment(IComments.PermitSparkComment memory permitSparkComment) internal {
|
|
345
|
+
// For permitSparkComment, we don't need to mint a token
|
|
346
|
+
vm.deal(permitSparkComment.comment.commenter, permitSparkComment.sparksQuantity * SPARKS_VALUE);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function _executePermitSparkComment(address executor, IComments.PermitSparkComment memory permitSparkComment, bytes memory signature) internal {
|
|
350
|
+
vm.prank(executor);
|
|
351
|
+
vm.deal(executor, permitSparkComment.sparksQuantity * SPARKS_VALUE);
|
|
352
|
+
comments.permitSparkComment{value: permitSparkComment.sparksQuantity * SPARKS_VALUE}(permitSparkComment, signature);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Helper functions
|
|
356
|
+
function _createPermitComment(address commenter, string memory text, uint64 sparksQuantity) internal returns (IComments.PermitComment memory) {
|
|
357
|
+
return
|
|
358
|
+
IComments.PermitComment({
|
|
359
|
+
contractAddress: address(mock1155),
|
|
360
|
+
tokenId: tokenId1,
|
|
361
|
+
commenter: commenter,
|
|
362
|
+
replyTo: emptyCommentIdentifier,
|
|
363
|
+
text: text,
|
|
364
|
+
sparksQuantity: sparksQuantity,
|
|
365
|
+
deadline: block.timestamp + 100,
|
|
366
|
+
nonce: bytes32("1"),
|
|
367
|
+
referrer: makeAddr("referrer"),
|
|
368
|
+
sourceChainId: block.chainid,
|
|
369
|
+
destinationChainId: block.chainid
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function _setupTokenAndSparks(IComments.PermitComment memory permitComment) internal {
|
|
374
|
+
mock1155.mint(permitComment.commenter, permitComment.tokenId, 1, "");
|
|
375
|
+
vm.deal(permitComment.commenter, permitComment.sparksQuantity * SPARKS_VALUE);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function _executePermitComment(address executor, IComments.PermitComment memory permitComment, bytes memory signature) internal {
|
|
379
|
+
vm.prank(executor);
|
|
380
|
+
comments.permitComment{value: permitComment.sparksQuantity * SPARKS_VALUE}(permitComment, signature);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function _assertCommentExists(IComments.CommentIdentifier memory commentIdentifier) internal view {
|
|
384
|
+
(, bool exists) = comments.hashAndCheckCommentExists(commentIdentifier);
|
|
385
|
+
assertTrue(exists);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function _signPermitComment(IComments.PermitComment memory permitComment, uint256 privateKey) internal view returns (bytes memory signature) {
|
|
389
|
+
bytes32 digest = comments.hashPermitComment(permitComment);
|
|
390
|
+
signature = _sign(privateKey, digest);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function _sign(uint256 privateKey, bytes32 digest) internal pure returns (bytes memory signature) {
|
|
394
|
+
(uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest);
|
|
395
|
+
return abi.encodePacked(r, s, v);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
|
|
5
|
+
import {IZoraCreator1155} from "../../src/interfaces/IZoraCreator1155.sol";
|
|
6
|
+
|
|
7
|
+
contract Mock1155 is ERC1155, IZoraCreator1155 {
|
|
8
|
+
/// @notice This user role allows for any action to be performed
|
|
9
|
+
uint256 public constant PERMISSION_BIT_ADMIN = 2 ** 1;
|
|
10
|
+
|
|
11
|
+
mapping(uint256 => address) public admins;
|
|
12
|
+
|
|
13
|
+
constructor() ERC1155("") {}
|
|
14
|
+
|
|
15
|
+
function isAdminOrRole(address user, uint256 tokenId, uint256 role) external view returns (bool) {
|
|
16
|
+
if (admins[tokenId] == user && role == PERMISSION_BIT_ADMIN) {
|
|
17
|
+
return true;
|
|
18
|
+
} else {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function _tokenExists(uint256 tokenId) internal view returns (bool) {
|
|
24
|
+
return admins[tokenId] != address(0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getCreatorRewardRecipient(uint256 tokenId) external view returns (address) {
|
|
28
|
+
if (!_tokenExists(tokenId)) {
|
|
29
|
+
revert("Token does not exist");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return admins[tokenId];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function createToken(uint256 tokenId, address creator) external {
|
|
36
|
+
admins[tokenId] = creator;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function supportsInterface(bytes4 interfaceId) public view override(ERC1155, IZoraCreator1155) returns (bool) {
|
|
40
|
+
return super.supportsInterface(interfaceId);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function mint(address to, uint256 id, uint256 amount, bytes memory data) external {
|
|
44
|
+
if (!_tokenExists(id)) {
|
|
45
|
+
revert("Token does not exist");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
_mint(to, id, amount, data);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
import {Mock1155} from "./Mock1155.sol";
|
|
5
|
+
import {IComments} from "../../src/interfaces/IComments.sol";
|
|
6
|
+
|
|
7
|
+
contract MockMinter {
|
|
8
|
+
uint256 MINT_FEE = 0.00111 ether;
|
|
9
|
+
uint256 constant SPARKS_VALUE = 0.000001 ether;
|
|
10
|
+
|
|
11
|
+
IComments immutable comments;
|
|
12
|
+
|
|
13
|
+
constructor(IComments _comments) {
|
|
14
|
+
comments = _comments;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
IComments.CommentIdentifier internal emptyCommentIdentifier;
|
|
18
|
+
|
|
19
|
+
function mintAndComment(uint256 quantity, address collection, uint256 tokenId, string calldata comment) external payable {
|
|
20
|
+
Mock1155(collection).mint(msg.sender, tokenId, quantity, "");
|
|
21
|
+
|
|
22
|
+
// get sparks value to send to comments contract
|
|
23
|
+
comments.delegateComment(msg.sender, collection, tokenId, comment, emptyCommentIdentifier);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function forwardComment(address collection, uint256 tokenId, string calldata comment) external {
|
|
27
|
+
comments.delegateComment(msg.sender, collection, tokenId, comment, emptyCommentIdentifier);
|
|
28
|
+
}
|
|
29
|
+
}
|