@zoralabs/comments-contracts 0.0.1 → 0.0.2
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/.turbo/turbo-build.log +49 -31
- package/README.md +10 -39
- package/abis/AddDelegateCommenterRole.json +9 -0
- package/abis/CallerAndCommenter.json +62 -0
- package/abis/CallerAndCommenterImpl.json +1218 -0
- package/abis/CallerAndCommenterMintAndCommentTest.json +771 -0
- package/abis/CallerAndCommenterSwapAndCommentTest.json +844 -0
- package/abis/CallerAndCommenterTestBase.json +577 -0
- package/abis/CommentsImpl.json +189 -59
- package/abis/CommentsImplConstants.json +106 -0
- package/abis/CommentsPermitTest.json +26 -6
- package/abis/CommentsTest.json +58 -10
- package/abis/Comments_mintAndCommentTest.json +11 -4
- package/abis/Comments_smartWallet.json +711 -0
- package/abis/DeployCallerAndCommenterImpl.json +9 -0
- package/abis/DeployImpl.json +0 -13
- package/abis/DeployNonDeterministic.json +0 -13
- package/abis/DeployScript.json +0 -13
- package/abis/EIP712Upgradeable.json +74 -0
- package/abis/EIP712UpgradeableWithChainId.json +49 -0
- package/abis/ERC20.json +310 -0
- package/abis/GenerateDeterministicParams.json +0 -13
- package/abis/ICallerAndCommenter.json +797 -0
- package/abis/IComments.json +629 -9
- package/abis/IERC20.json +39 -42
- package/abis/IERC20Metadata.json +224 -0
- package/abis/{CommentsDeployerBase.json → IMultiOwnable.json} +8 -2
- package/abis/IProtocolRewards.json +19 -0
- package/abis/ISecondarySwap.json +45 -0
- package/abis/IZoraCreator1155.json +51 -0
- package/abis/IZoraTimedSaleStrategy.json +91 -0
- package/abis/Mock1155.json +75 -1
- package/abis/Mock1155NoCreatorRewardRecipient.json +605 -0
- package/abis/Mock1155NoOwner.json +566 -0
- package/abis/{MockMinter.json → MockDelegateCommenter.json} +12 -2
- package/abis/MockERC20z.json +315 -0
- package/abis/MockMultiOwnable.json +212 -0
- package/abis/MockSecondarySwap.json +95 -0
- package/abis/MockZoraTimedSale.json +139 -0
- package/abis/Ownable2StepUpgradeable.json +138 -0
- package/abis/UnorderedNoncesUpgradeable.json +4 -4
- package/addresses/1.json +9 -0
- package/addresses/10.json +9 -0
- package/addresses/11155111.json +9 -0
- package/addresses/11155420.json +9 -0
- package/addresses/42161.json +9 -0
- package/addresses/7777777.json +9 -0
- package/addresses/81457.json +9 -0
- package/addresses/8453.json +9 -0
- package/addresses/84532.json +9 -0
- package/addresses/999999999.json +7 -2
- package/deterministicConfig/callerAndCommenter.json +8 -0
- package/deterministicConfig/comments.json +2 -2
- package/dist/index.cjs +724 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +723 -35
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/wagmiGenerated.d.ts +1102 -57
- package/dist/wagmiGenerated.d.ts.map +1 -1
- package/package/types.ts +4 -1
- package/package/wagmiGenerated.ts +728 -32
- package/package.json +12 -11
- package/script/AddDelegateCommenterRole.s.sol +24 -0
- package/script/CommentsDeployerBase.sol +102 -19
- package/script/Deploy.s.sol +2 -44
- package/script/DeployCallerAndCommenterImpl.s.sol +29 -0
- package/script/DeployImpl.s.sol +1 -0
- package/script/DeployNonDeterministic.s.sol +22 -13
- package/script/GenerateDeterministicParams.s.sol +32 -4
- package/scripts/generateCommentsTestData.ts +170 -79
- package/src/CommentsImpl.sol +267 -134
- package/src/CommentsImplConstants.sol +44 -0
- package/src/interfaces/ICallerAndCommenter.sol +215 -0
- package/src/interfaces/IComments.sol +189 -42
- package/src/interfaces/IMultiOwnable.sol +10 -0
- package/src/interfaces/ISecondarySwap.sol +40 -0
- package/src/interfaces/IZoraCreator1155.sol +6 -1
- package/src/interfaces/IZoraCreator1155TypesV1.sol +46 -0
- package/src/interfaces/IZoraTimedSaleStrategy.sol +25 -0
- package/src/proxy/CallerAndCommenter.sol +43 -0
- package/src/utils/CallerAndCommenterImpl.sol +376 -0
- package/src/utils/EIP712UpgradeableWithChainId.sol +12 -23
- package/src/version/ContractVersionBase.sol +1 -1
- package/test/CallerAndCommenterTestBase.sol +77 -0
- package/test/CallerAndCommenter_mintAndComment.t copy.sol +214 -0
- package/test/CallerAndCommenter_swapAndComment.t.sol +523 -0
- package/test/Comments.t.sol +166 -29
- package/test/CommentsTestBase.sol +12 -20
- package/test/Comments_delegateComment.t.sol +129 -0
- package/test/Comments_permit.t.sol +131 -44
- package/test/Comments_smartWallet.t.sol +152 -0
- package/test/mocks/Mock1155.sol +12 -1
- package/test/mocks/Mock1155NoCreatorRewardRecipient.sol +65 -0
- package/test/mocks/Mock1155NoOwner.sol +53 -0
- package/test/mocks/MockDelegateCommenter.sol +36 -0
- package/test/mocks/MockIZoraCreator1155.sol +16 -0
- package/test/mocks/MockSecondarySwap.sol +30 -0
- package/test/mocks/MockZoraTimedSale.sol +38 -0
- package/wagmi.config.ts +3 -1
- package/abis/ProxyDeployerScript.json +0 -15
- package/scripts/backfillComments.ts +0 -176
- package/scripts/queries.ts +0 -73
- package/scripts/queryAndSaveComments.ts +0 -48
- package/scripts/queryQuantityOfComments.ts +0 -53
- package/scripts/writeComments.ts +0 -198
- package/src/deployments/CommentsDeployment.sol +0 -14
- package/test/Comments_mintAndComment.t.sol +0 -101
- package/test/mocks/MockMinter.sol +0 -29
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
import {IComments} from "../src/interfaces/IComments.sol";
|
|
5
|
+
import {ICallerAndCommenter} from "../src/interfaces/ICallerAndCommenter.sol";
|
|
6
|
+
import {CallerAndCommenterTestBase} from "./CallerAndCommenterTestBase.sol";
|
|
7
|
+
import {ISecondarySwap} from "../src/interfaces/ISecondarySwap.sol";
|
|
8
|
+
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
9
|
+
import {CallerAndCommenterImpl} from "../src/utils/CallerAndCommenterImpl.sol";
|
|
10
|
+
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
11
|
+
import {IERC1155} from "@openzeppelin/contracts/interfaces/IERC1155.sol";
|
|
12
|
+
import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
|
|
13
|
+
|
|
14
|
+
contract CallerAndCommenterSwapAndCommentTest is CallerAndCommenterTestBase {
|
|
15
|
+
function testBuyOnSecondaryAndComment() public {
|
|
16
|
+
// setup the sale so that we have a link between the erc20z and the 1155
|
|
17
|
+
address erc20z = mockMinter.setSale(address(mock1155), tokenId1);
|
|
18
|
+
|
|
19
|
+
uint256 quantity = 5;
|
|
20
|
+
|
|
21
|
+
address excessRefundRecipient = makeAddr("excessRefundRecipient");
|
|
22
|
+
uint256 maxEthToSpend = 2 ether;
|
|
23
|
+
uint160 sqrtPriceLimitX96 = 1000;
|
|
24
|
+
string memory comment = "test comment";
|
|
25
|
+
|
|
26
|
+
IComments.CommentIdentifier memory expectedCommentIdentifier = _expectedCommentIdentifier(commenter, address(mock1155), tokenId1);
|
|
27
|
+
bytes32 expectedCommentId = comments.hashCommentIdentifier(expectedCommentIdentifier);
|
|
28
|
+
|
|
29
|
+
uint256 valueToSpend = 1 ether;
|
|
30
|
+
vm.deal(commenter, valueToSpend);
|
|
31
|
+
|
|
32
|
+
vm.expectEmit(true, true, true, true);
|
|
33
|
+
emit IComments.Commented(expectedCommentId, expectedCommentIdentifier, bytes32(0), emptyCommentIdentifier, 0, comment, block.timestamp, address(0));
|
|
34
|
+
vm.expectEmit(true, true, true, true);
|
|
35
|
+
emit ICallerAndCommenter.SwappedOnSecondaryAndCommented(
|
|
36
|
+
expectedCommentId,
|
|
37
|
+
expectedCommentIdentifier,
|
|
38
|
+
quantity,
|
|
39
|
+
comment,
|
|
40
|
+
ICallerAndCommenter.SwapDirection.BUY
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
vm.expectCall(
|
|
44
|
+
address(mockSecondarySwap),
|
|
45
|
+
valueToSpend,
|
|
46
|
+
abi.encodeWithSelector(ISecondarySwap.buy1155.selector, erc20z, quantity, commenter, excessRefundRecipient, maxEthToSpend, sqrtPriceLimitX96)
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
vm.prank(commenter);
|
|
50
|
+
callerAndCommenter.buyOnSecondaryAndComment{value: valueToSpend}({
|
|
51
|
+
commenter: commenter,
|
|
52
|
+
quantity: quantity,
|
|
53
|
+
collection: address(mock1155),
|
|
54
|
+
tokenId: tokenId1,
|
|
55
|
+
excessRefundRecipient: payable(excessRefundRecipient),
|
|
56
|
+
maxEthToSpend: maxEthToSpend,
|
|
57
|
+
sqrtPriceLimitX96: sqrtPriceLimitX96,
|
|
58
|
+
comment: comment
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function testBuyOnSecondaryAndComment_revertsWhenSaleNotSet() public {
|
|
63
|
+
vm.expectRevert(abi.encodeWithSelector(ICallerAndCommenter.SaleNotSet.selector, address(mock1155), tokenId1));
|
|
64
|
+
vm.prank(commenter);
|
|
65
|
+
callerAndCommenter.buyOnSecondaryAndComment({
|
|
66
|
+
commenter: commenter,
|
|
67
|
+
quantity: 1,
|
|
68
|
+
collection: address(mock1155),
|
|
69
|
+
tokenId: tokenId1,
|
|
70
|
+
excessRefundRecipient: payable(address(0)),
|
|
71
|
+
maxEthToSpend: 0,
|
|
72
|
+
sqrtPriceLimitX96: 0,
|
|
73
|
+
comment: "test comment"
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function testBuyOnSecondaryAndComment_revertsWhenCommenterMismatch() public {
|
|
78
|
+
address commenter2 = makeAddr("commenter2");
|
|
79
|
+
vm.expectRevert(abi.encodeWithSelector(ICallerAndCommenter.CommenterMismatch.selector, commenter2, commenter));
|
|
80
|
+
vm.prank(commenter2);
|
|
81
|
+
callerAndCommenter.buyOnSecondaryAndComment({
|
|
82
|
+
commenter: commenter,
|
|
83
|
+
quantity: 1,
|
|
84
|
+
collection: address(mock1155),
|
|
85
|
+
tokenId: tokenId1,
|
|
86
|
+
excessRefundRecipient: payable(address(0)),
|
|
87
|
+
maxEthToSpend: 0,
|
|
88
|
+
sqrtPriceLimitX96: 0,
|
|
89
|
+
comment: "test comment"
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function testBuyOnSecondaryAndCommentWhenNoCommentDoesNotComment() public {
|
|
94
|
+
uint256 quantity = 1;
|
|
95
|
+
uint256 maxEthToSpend = 0.2 ether;
|
|
96
|
+
uint160 sqrtPriceLimitX96 = 0;
|
|
97
|
+
address excessRefundRecipient = address(0);
|
|
98
|
+
|
|
99
|
+
mockMinter.setSale(address(mock1155), tokenId1);
|
|
100
|
+
|
|
101
|
+
vm.prank(commenter);
|
|
102
|
+
IComments.CommentIdentifier memory result = callerAndCommenter.buyOnSecondaryAndComment({
|
|
103
|
+
commenter: commenter,
|
|
104
|
+
quantity: quantity,
|
|
105
|
+
collection: address(mock1155),
|
|
106
|
+
tokenId: tokenId1,
|
|
107
|
+
excessRefundRecipient: payable(excessRefundRecipient),
|
|
108
|
+
maxEthToSpend: maxEthToSpend,
|
|
109
|
+
sqrtPriceLimitX96: sqrtPriceLimitX96,
|
|
110
|
+
comment: ""
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
assertEq(result.commenter, address(0));
|
|
114
|
+
assertEq(result.contractAddress, address(0));
|
|
115
|
+
assertEq(result.tokenId, 0);
|
|
116
|
+
assertEq(result.nonce, bytes32(0));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function upgradeForkCallerAndCommenterToNewImplementation() internal {
|
|
120
|
+
// upgrade the current caller and commenter on the fork to the new implementation
|
|
121
|
+
address COMMENTS = 0x7777777C2B3132e03a65721a41745C07170a5877;
|
|
122
|
+
address ZORA_TIMED_SALE_STRATEGY = 0x777777722D078c97c6ad07d9f36801e653E356Ae;
|
|
123
|
+
address SECONDARY_SWAP = 0x777777EDF27Ac61671e3D5718b10bf6a8802f9f1;
|
|
124
|
+
// deploy the new implementation
|
|
125
|
+
CallerAndCommenterImpl callerAndCallerImp = new CallerAndCommenterImpl(COMMENTS, ZORA_TIMED_SALE_STRATEGY, SECONDARY_SWAP, SPARKS_VALUE);
|
|
126
|
+
// here we override the caller and commenter with the current one on the fork
|
|
127
|
+
callerAndCommenter = ICallerAndCommenter(0x77777775C5074b74540d9cC63Dd840A8c692B4B5);
|
|
128
|
+
// upgrade to the new implementation
|
|
129
|
+
address owner = OwnableUpgradeable(address(callerAndCommenter)).owner();
|
|
130
|
+
vm.prank(owner);
|
|
131
|
+
UUPSUpgradeable(address(callerAndCommenter)).upgradeToAndCall(address(callerAndCallerImp), "");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function testFork_buyOnSecondaryAndComment() public {
|
|
135
|
+
// upgrade the forked caller and commenter to the new implementation
|
|
136
|
+
upgradeForkCallerAndCommenterToNewImplementation();
|
|
137
|
+
// this is a known zora test collection where we can secondary swap
|
|
138
|
+
address test1155Address = 0xE79585bF83BbBfAE0fB80222b0a72F2c1D040612;
|
|
139
|
+
uint256 testTokenId = 1;
|
|
140
|
+
|
|
141
|
+
address excessRefundRecipient = makeAddr("excessRefundRecipient");
|
|
142
|
+
uint256 maxEthToSpend = 237222215770897;
|
|
143
|
+
uint160 sqrtPriceLimitX96 = 0;
|
|
144
|
+
string memory comment = "test comment";
|
|
145
|
+
|
|
146
|
+
IComments.CommentIdentifier memory expectedCommentIdentifier = IComments.CommentIdentifier({
|
|
147
|
+
commenter: commenter,
|
|
148
|
+
contractAddress: test1155Address,
|
|
149
|
+
tokenId: testTokenId,
|
|
150
|
+
// we need to get the nonce from the fork comments contract
|
|
151
|
+
nonce: callerAndCommenter.comments().nextNonce()
|
|
152
|
+
});
|
|
153
|
+
bytes32 expectedCommentId = callerAndCommenter.comments().hashCommentIdentifier(expectedCommentIdentifier);
|
|
154
|
+
|
|
155
|
+
uint256 quantity = 1;
|
|
156
|
+
uint256 valueToSpend = maxEthToSpend;
|
|
157
|
+
vm.deal(commenter, valueToSpend);
|
|
158
|
+
|
|
159
|
+
vm.expectEmit(true, true, true, true);
|
|
160
|
+
emit IComments.Commented(expectedCommentId, expectedCommentIdentifier, bytes32(0), emptyCommentIdentifier, 0, comment, block.timestamp, address(0));
|
|
161
|
+
vm.expectEmit(true, true, true, true);
|
|
162
|
+
emit ICallerAndCommenter.SwappedOnSecondaryAndCommented(
|
|
163
|
+
expectedCommentId,
|
|
164
|
+
expectedCommentIdentifier,
|
|
165
|
+
quantity,
|
|
166
|
+
comment,
|
|
167
|
+
ICallerAndCommenter.SwapDirection.BUY
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
// call the caller and commenter contract
|
|
171
|
+
vm.prank(commenter);
|
|
172
|
+
callerAndCommenter.buyOnSecondaryAndComment{value: valueToSpend}({
|
|
173
|
+
commenter: commenter,
|
|
174
|
+
quantity: quantity,
|
|
175
|
+
collection: test1155Address,
|
|
176
|
+
tokenId: testTokenId,
|
|
177
|
+
excessRefundRecipient: payable(excessRefundRecipient),
|
|
178
|
+
maxEthToSpend: maxEthToSpend,
|
|
179
|
+
sqrtPriceLimitX96: sqrtPriceLimitX96,
|
|
180
|
+
comment: comment
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function testPermitBuyOnSecondaryAndComment() public {
|
|
185
|
+
uint256 quantity = 5;
|
|
186
|
+
uint256 valueToSpend = 1 ether;
|
|
187
|
+
|
|
188
|
+
address contractAddress = address(mock1155);
|
|
189
|
+
uint256 tokenId = tokenId1;
|
|
190
|
+
|
|
191
|
+
string memory comment = "test comment";
|
|
192
|
+
|
|
193
|
+
address erc20z = mockMinter.setSale(contractAddress, tokenId);
|
|
194
|
+
|
|
195
|
+
ICallerAndCommenter.PermitBuyOnSecondaryAndComment memory permit = _createPermitBuy(
|
|
196
|
+
commenter,
|
|
197
|
+
quantity,
|
|
198
|
+
contractAddress,
|
|
199
|
+
tokenId,
|
|
200
|
+
2 ether,
|
|
201
|
+
1000,
|
|
202
|
+
comment,
|
|
203
|
+
block.timestamp + 1 hours
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
bytes memory signature = _signPermit(permit, commenterPrivateKey);
|
|
207
|
+
|
|
208
|
+
IComments.CommentIdentifier memory expectedCommentIdentifier = _expectedCommentIdentifier(commenter, contractAddress, tokenId);
|
|
209
|
+
|
|
210
|
+
bytes32 expectedCommentId = comments.hashCommentIdentifier(expectedCommentIdentifier);
|
|
211
|
+
|
|
212
|
+
vm.deal(commenter, valueToSpend);
|
|
213
|
+
vm.expectEmit(true, true, true, true);
|
|
214
|
+
emit IComments.Commented(expectedCommentId, expectedCommentIdentifier, bytes32(0), emptyCommentIdentifier, 0, comment, block.timestamp, address(0));
|
|
215
|
+
vm.expectEmit(true, true, true, true);
|
|
216
|
+
emit ICallerAndCommenter.SwappedOnSecondaryAndCommented(
|
|
217
|
+
expectedCommentId,
|
|
218
|
+
expectedCommentIdentifier,
|
|
219
|
+
quantity,
|
|
220
|
+
comment,
|
|
221
|
+
ICallerAndCommenter.SwapDirection.BUY
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
vm.expectCall(
|
|
225
|
+
address(mockSecondarySwap),
|
|
226
|
+
valueToSpend,
|
|
227
|
+
abi.encodeWithSelector(
|
|
228
|
+
ISecondarySwap.buy1155.selector,
|
|
229
|
+
erc20z,
|
|
230
|
+
quantity,
|
|
231
|
+
commenter,
|
|
232
|
+
permit.commenter,
|
|
233
|
+
permit.maxEthToSpend,
|
|
234
|
+
permit.sqrtPriceLimitX96
|
|
235
|
+
)
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
IComments.CommentIdentifier memory result = callerAndCommenter.permitBuyOnSecondaryAndComment{value: valueToSpend}(permit, signature);
|
|
239
|
+
|
|
240
|
+
assertEq(result.commenter, commenter);
|
|
241
|
+
assertEq(result.contractAddress, contractAddress);
|
|
242
|
+
assertEq(result.tokenId, tokenId);
|
|
243
|
+
assertEq(result.nonce, bytes32(0));
|
|
244
|
+
|
|
245
|
+
// validate that the comment was created
|
|
246
|
+
(, bool exists) = comments.hashAndCheckCommentExists(expectedCommentIdentifier);
|
|
247
|
+
assertEq(exists, true);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function testPermitBuyOnSecondaryAndComment_ExpiredDeadline() public {
|
|
251
|
+
ICallerAndCommenter.PermitBuyOnSecondaryAndComment memory permit = _createPermitBuy(
|
|
252
|
+
commenter,
|
|
253
|
+
1,
|
|
254
|
+
address(mock1155),
|
|
255
|
+
tokenId1,
|
|
256
|
+
1 ether,
|
|
257
|
+
1000,
|
|
258
|
+
"test comment",
|
|
259
|
+
block.timestamp - 1 // Expired deadline
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
bytes memory signature = _signPermit(permit, commenterPrivateKey);
|
|
263
|
+
|
|
264
|
+
vm.expectRevert(abi.encodeWithSelector(IComments.ERC2612ExpiredSignature.selector, permit.deadline));
|
|
265
|
+
callerAndCommenter.permitBuyOnSecondaryAndComment{value: 1 ether}(permit, signature);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function testPermitBuyOnSecondaryAndComment_InvalidSignature() public {
|
|
269
|
+
ICallerAndCommenter.PermitBuyOnSecondaryAndComment memory permit = _createPermitBuy(
|
|
270
|
+
commenter,
|
|
271
|
+
1,
|
|
272
|
+
address(mock1155),
|
|
273
|
+
tokenId1,
|
|
274
|
+
1 ether,
|
|
275
|
+
1000,
|
|
276
|
+
"test comment",
|
|
277
|
+
block.timestamp + 1 hours
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
bytes memory signature = _signPermit(permit, 5); // Wrong signer
|
|
281
|
+
|
|
282
|
+
vm.expectRevert(IComments.InvalidSignature.selector);
|
|
283
|
+
callerAndCommenter.permitBuyOnSecondaryAndComment{value: 1 ether}(permit, signature);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function testPermitBuyOnSecondaryAndComment_IncorrectDestinationChain() public {
|
|
287
|
+
ICallerAndCommenter.PermitBuyOnSecondaryAndComment memory permit = _createPermitBuy(
|
|
288
|
+
commenter,
|
|
289
|
+
1,
|
|
290
|
+
address(mock1155),
|
|
291
|
+
tokenId1,
|
|
292
|
+
1 ether,
|
|
293
|
+
1000,
|
|
294
|
+
"test comment",
|
|
295
|
+
block.timestamp + 1 hours
|
|
296
|
+
);
|
|
297
|
+
permit.destinationChainId = uint32(block.chainid) + 1; // Incorrect destination chain
|
|
298
|
+
|
|
299
|
+
bytes memory signature = _signPermit(permit, commenterPrivateKey);
|
|
300
|
+
|
|
301
|
+
vm.expectRevert(abi.encodeWithSelector(ICallerAndCommenter.IncorrectDestinationChain.selector, permit.destinationChainId));
|
|
302
|
+
callerAndCommenter.permitBuyOnSecondaryAndComment{value: 1 ether}(permit, signature);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function testSellOnSecondaryAndComment() public {
|
|
306
|
+
// setup the sale so that we have a link between the erc20z and the 1155
|
|
307
|
+
mockMinter.setSale(address(mock1155), tokenId1);
|
|
308
|
+
|
|
309
|
+
uint256 quantityToSwap = 5;
|
|
310
|
+
mock1155.mint(commenter, tokenId1, quantityToSwap, "");
|
|
311
|
+
|
|
312
|
+
address payable recipient = payable(makeAddr("recipient"));
|
|
313
|
+
uint256 minEthToAcquire = 1 ether;
|
|
314
|
+
uint160 sqrtPriceLimitX96 = 1000;
|
|
315
|
+
string memory comment = "test comment";
|
|
316
|
+
|
|
317
|
+
IComments.CommentIdentifier memory expectedCommentIdentifier = _expectedCommentIdentifier(commenter, address(mock1155), tokenId1);
|
|
318
|
+
bytes32 expectedCommentId = comments.hashCommentIdentifier(expectedCommentIdentifier);
|
|
319
|
+
|
|
320
|
+
bytes memory expectedData = abi.encode(recipient, minEthToAcquire, sqrtPriceLimitX96);
|
|
321
|
+
|
|
322
|
+
// commenter needs to approve the caller to transfer the 1155s
|
|
323
|
+
// since it is to transfer to the secondary swap
|
|
324
|
+
vm.prank(commenter);
|
|
325
|
+
IERC1155(address(mock1155)).setApprovalForAll(address(callerAndCommenter), true);
|
|
326
|
+
|
|
327
|
+
vm.expectEmit(true, true, true, true);
|
|
328
|
+
emit IComments.Commented({
|
|
329
|
+
commentId: expectedCommentId,
|
|
330
|
+
commentIdentifier: expectedCommentIdentifier,
|
|
331
|
+
replyToId: bytes32(0),
|
|
332
|
+
replyTo: emptyCommentIdentifier,
|
|
333
|
+
sparksQuantity: 1,
|
|
334
|
+
text: comment,
|
|
335
|
+
timestamp: block.timestamp,
|
|
336
|
+
referrer: address(0)
|
|
337
|
+
});
|
|
338
|
+
vm.expectEmit(true, true, true, true);
|
|
339
|
+
emit ICallerAndCommenter.SwappedOnSecondaryAndCommented(
|
|
340
|
+
expectedCommentId,
|
|
341
|
+
expectedCommentIdentifier,
|
|
342
|
+
quantityToSwap,
|
|
343
|
+
comment,
|
|
344
|
+
ICallerAndCommenter.SwapDirection.SELL
|
|
345
|
+
);
|
|
346
|
+
|
|
347
|
+
// make sure the mock secondary swap received the 1155s
|
|
348
|
+
// using the expected call
|
|
349
|
+
vm.expectCall(
|
|
350
|
+
address(mockSecondarySwap),
|
|
351
|
+
0,
|
|
352
|
+
abi.encodeWithSelector(IERC1155Receiver.onERC1155Received.selector, address(callerAndCommenter), commenter, tokenId1, quantityToSwap, expectedData)
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
vm.deal(commenter, SPARKS_VALUE);
|
|
356
|
+
vm.prank(commenter);
|
|
357
|
+
callerAndCommenter.sellOnSecondaryAndComment{value: SPARKS_VALUE}(
|
|
358
|
+
commenter,
|
|
359
|
+
quantityToSwap,
|
|
360
|
+
address(mock1155),
|
|
361
|
+
tokenId1,
|
|
362
|
+
recipient,
|
|
363
|
+
minEthToAcquire,
|
|
364
|
+
sqrtPriceLimitX96,
|
|
365
|
+
comment
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
// make sure the mock secondary swap received the 1155s
|
|
369
|
+
assertEq(IERC1155(address(mock1155)).balanceOf(address(mockSecondarySwap), tokenId1), quantityToSwap);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function testFork_sellOnSecondaryAndComment() public {
|
|
373
|
+
// upgrade the forked caller and commenter to the new implementation
|
|
374
|
+
upgradeForkCallerAndCommenterToNewImplementation();
|
|
375
|
+
// this is a known zora test collection where we can secondary swap
|
|
376
|
+
address test1155Address = 0xE79585bF83BbBfAE0fB80222b0a72F2c1D040612;
|
|
377
|
+
uint256 testTokenId = 1;
|
|
378
|
+
|
|
379
|
+
uint256 quantityToBuy = 5;
|
|
380
|
+
|
|
381
|
+
uint256 maxEthToSpend = 237222215770897 * quantityToBuy;
|
|
382
|
+
uint256 valueToSpend = maxEthToSpend;
|
|
383
|
+
|
|
384
|
+
// first we need to buy the 1155s on secondary
|
|
385
|
+
vm.deal(commenter, valueToSpend);
|
|
386
|
+
vm.prank(commenter);
|
|
387
|
+
callerAndCommenter.buyOnSecondaryAndComment{value: valueToSpend}({
|
|
388
|
+
commenter: commenter,
|
|
389
|
+
quantity: quantityToBuy,
|
|
390
|
+
collection: test1155Address,
|
|
391
|
+
tokenId: testTokenId,
|
|
392
|
+
excessRefundRecipient: payable(commenter),
|
|
393
|
+
maxEthToSpend: maxEthToSpend,
|
|
394
|
+
sqrtPriceLimitX96: 0,
|
|
395
|
+
comment: "test comment when buying"
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
// now we can sell the 1155s on secondary
|
|
399
|
+
|
|
400
|
+
uint256 quantityToSell = 3;
|
|
401
|
+
string memory sellingComment = "test comment when selling";
|
|
402
|
+
|
|
403
|
+
vm.prank(commenter);
|
|
404
|
+
IERC1155(address(test1155Address)).setApprovalForAll(address(callerAndCommenter), true);
|
|
405
|
+
|
|
406
|
+
// perform the sell
|
|
407
|
+
vm.deal(commenter, SPARKS_VALUE);
|
|
408
|
+
vm.prank(commenter);
|
|
409
|
+
callerAndCommenter.sellOnSecondaryAndComment{value: SPARKS_VALUE}({
|
|
410
|
+
commenter: commenter,
|
|
411
|
+
quantity: quantityToSell,
|
|
412
|
+
collection: test1155Address,
|
|
413
|
+
tokenId: testTokenId,
|
|
414
|
+
recipient: payable(commenter),
|
|
415
|
+
minEthToAcquire: 0,
|
|
416
|
+
sqrtPriceLimitX96: 0,
|
|
417
|
+
comment: sellingComment
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function testSellOnSecondaryAndComment_CommenterMismatch() public {
|
|
422
|
+
vm.expectRevert(abi.encodeWithSelector(ICallerAndCommenter.CommenterMismatch.selector, commenter, makeAddr("other")));
|
|
423
|
+
vm.prank(commenter);
|
|
424
|
+
callerAndCommenter.sellOnSecondaryAndComment(makeAddr("other"), 1, address(mock1155), tokenId1, payable(address(0)), 1 ether, 1000, "test comment");
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
function testSellOnSecondaryAndComment_SaleNotSet() public {
|
|
428
|
+
uint256 quantityToSwap = 5;
|
|
429
|
+
mock1155.mint(commenter, tokenId1, quantityToSwap, "");
|
|
430
|
+
vm.prank(commenter);
|
|
431
|
+
IERC1155(address(mock1155)).setApprovalForAll(address(callerAndCommenter), true);
|
|
432
|
+
|
|
433
|
+
vm.expectRevert(ISecondarySwap.SaleNotSet.selector);
|
|
434
|
+
vm.prank(commenter);
|
|
435
|
+
vm.deal(commenter, SPARKS_VALUE);
|
|
436
|
+
callerAndCommenter.sellOnSecondaryAndComment{value: SPARKS_VALUE}(
|
|
437
|
+
commenter,
|
|
438
|
+
1,
|
|
439
|
+
address(mock1155),
|
|
440
|
+
tokenId1,
|
|
441
|
+
payable(address(0)),
|
|
442
|
+
1 ether,
|
|
443
|
+
1000,
|
|
444
|
+
"test comment"
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function testSellOnSecondaryAndComment_RevertsWhenNotOneSparkAndACommentIsSent(uint16 sparksQuantity, bool commentIsSent) public {
|
|
449
|
+
uint256 valueToSend = sparksQuantity * SPARKS_VALUE;
|
|
450
|
+
// setup the sale so that we have a link between the erc20z and the 1155
|
|
451
|
+
mockMinter.setSale(address(mock1155), tokenId1);
|
|
452
|
+
|
|
453
|
+
uint256 quantityToSwap = 5;
|
|
454
|
+
mock1155.mint(commenter, tokenId1, quantityToSwap, "");
|
|
455
|
+
|
|
456
|
+
address recipient = makeAddr("recipient");
|
|
457
|
+
uint256 minEthToAcquire = 1 ether;
|
|
458
|
+
uint160 sqrtPriceLimitX96 = 1000;
|
|
459
|
+
string memory comment = commentIsSent ? "test comment" : "";
|
|
460
|
+
|
|
461
|
+
// commenter needs to approve the caller to transfer the 1155s
|
|
462
|
+
// since it is to transfer to the secondary swap
|
|
463
|
+
vm.prank(commenter);
|
|
464
|
+
IERC1155(address(mock1155)).setApprovalForAll(address(callerAndCommenter), true);
|
|
465
|
+
|
|
466
|
+
// if we are sending a comment, we should be required to send one spark
|
|
467
|
+
if (commentIsSent) {
|
|
468
|
+
if (sparksQuantity != 1) {
|
|
469
|
+
vm.expectRevert(abi.encodeWithSelector(ICallerAndCommenter.WrongValueSent.selector, SPARKS_VALUE, valueToSend));
|
|
470
|
+
}
|
|
471
|
+
} else {
|
|
472
|
+
// if we are not sending a comment, we should not send any ETH
|
|
473
|
+
if (valueToSend != 0) {
|
|
474
|
+
vm.expectRevert(abi.encodeWithSelector(ICallerAndCommenter.WrongValueSent.selector, 0, valueToSend));
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
vm.deal(commenter, valueToSend);
|
|
479
|
+
vm.prank(commenter);
|
|
480
|
+
callerAndCommenter.sellOnSecondaryAndComment{value: valueToSend}(
|
|
481
|
+
commenter,
|
|
482
|
+
quantityToSwap,
|
|
483
|
+
address(mock1155),
|
|
484
|
+
tokenId1,
|
|
485
|
+
payable(recipient),
|
|
486
|
+
minEthToAcquire,
|
|
487
|
+
sqrtPriceLimitX96,
|
|
488
|
+
comment
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function _createPermitBuy(
|
|
493
|
+
address _commenter,
|
|
494
|
+
uint256 _quantity,
|
|
495
|
+
address _collection,
|
|
496
|
+
uint256 _tokenId,
|
|
497
|
+
uint256 _maxEthToSpend,
|
|
498
|
+
uint160 _sqrtPriceLimitX96,
|
|
499
|
+
string memory _comment,
|
|
500
|
+
uint256 _deadline
|
|
501
|
+
) internal view returns (ICallerAndCommenter.PermitBuyOnSecondaryAndComment memory) {
|
|
502
|
+
return
|
|
503
|
+
ICallerAndCommenter.PermitBuyOnSecondaryAndComment({
|
|
504
|
+
commenter: _commenter,
|
|
505
|
+
quantity: _quantity,
|
|
506
|
+
collection: _collection,
|
|
507
|
+
tokenId: _tokenId,
|
|
508
|
+
maxEthToSpend: _maxEthToSpend,
|
|
509
|
+
sqrtPriceLimitX96: _sqrtPriceLimitX96,
|
|
510
|
+
comment: _comment,
|
|
511
|
+
deadline: _deadline,
|
|
512
|
+
nonce: bytes32(0),
|
|
513
|
+
sourceChainId: uint32(block.chainid),
|
|
514
|
+
destinationChainId: uint32(block.chainid)
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
function _signPermit(ICallerAndCommenter.PermitBuyOnSecondaryAndComment memory _permit, uint256 _privateKey) internal view returns (bytes memory) {
|
|
519
|
+
bytes32 digest = callerAndCommenter.hashPermitBuyOnSecondaryAndComment(_permit);
|
|
520
|
+
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_privateKey, digest);
|
|
521
|
+
return abi.encodePacked(r, s, v);
|
|
522
|
+
}
|
|
523
|
+
}
|