@croptop/core-v6 0.0.22 → 0.0.23
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/CHANGE_LOG.md
CHANGED
|
@@ -103,6 +103,10 @@ Posts can now include a `splitPercent` and an array of `splits` (JBSplit[]) that
|
|
|
103
103
|
|
|
104
104
|
## 3. Event Changes
|
|
105
105
|
|
|
106
|
+
Indexer note:
|
|
107
|
+
- event names are stable, but embedded struct payloads changed ABI shape;
|
|
108
|
+
- if your graph decodes `ConfigurePostingCriteria` or `Mint`, update the event-decoding schema for the new `maximumSplitPercent`, `splitPercent`, and `splits` fields.
|
|
109
|
+
|
|
106
110
|
No event signatures were changed. Both versions emit the same two events:
|
|
107
111
|
- `ConfigurePostingCriteria(address indexed hook, CTAllowedPost allowedPost, address caller)` — note that the `CTAllowedPost` struct gained a `maximumSplitPercent` field, which changes the ABI encoding of this event's data.
|
|
108
112
|
- `Mint(uint256 indexed projectId, IJB721TiersHook indexed hook, address indexed nftBeneficiary, address feeBeneficiary, CTPost[] posts, uint256 postValue, uint256 txValue, address caller)` — note that the `CTPost` struct gained `splitPercent` and `splits` fields, which changes the ABI encoding of this event's data.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@croptop/core-v6",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,18 +16,18 @@
|
|
|
16
16
|
"artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'croptop-core-v5'"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@bananapus/721-hook-v6": "^0.0.
|
|
20
|
-
"@bananapus/address-registry-v6": "^0.0.
|
|
21
|
-
"@bananapus/buyback-hook-v6": "^0.0.
|
|
22
|
-
"@bananapus/core-v6": "^0.0.
|
|
23
|
-
"@bananapus/ownable-v6": "^0.0.
|
|
19
|
+
"@bananapus/721-hook-v6": "^0.0.22",
|
|
20
|
+
"@bananapus/address-registry-v6": "^0.0.16",
|
|
21
|
+
"@bananapus/buyback-hook-v6": "^0.0.22",
|
|
22
|
+
"@bananapus/core-v6": "^0.0.28",
|
|
23
|
+
"@bananapus/ownable-v6": "^0.0.15",
|
|
24
24
|
"@bananapus/permission-ids-v6": "^0.0.14",
|
|
25
|
-
"@bananapus/router-terminal-v6": "^0.0.
|
|
26
|
-
"@bananapus/suckers-v6": "^0.0.
|
|
25
|
+
"@bananapus/router-terminal-v6": "^0.0.21",
|
|
26
|
+
"@bananapus/suckers-v6": "^0.0.18",
|
|
27
27
|
"@openzeppelin/contracts": "^5.6.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@rev-net/core-v6": "^0.0.
|
|
30
|
+
"@rev-net/core-v6": "^0.0.17",
|
|
31
31
|
"@sphinx-labs/plugins": "^0.33.1"
|
|
32
32
|
}
|
|
33
33
|
}
|
package/script/Deploy.s.sol
CHANGED
|
@@ -64,9 +64,28 @@ contract DeployScript is Script, Sphinx {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
function deploy() public sphinx {
|
|
67
|
-
// If the fee project id is 0, then we want to deploy a new fee project
|
|
67
|
+
// If the fee project id is 0, then we want to deploy a new fee project — but only if the publisher
|
|
68
|
+
// singleton doesn't already exist. Re-running with FEE_PROJECT_ID=0 would create a second fee project
|
|
69
|
+
// with different CREATE2 addresses, stranding the previous suite.
|
|
68
70
|
if (FEE_PROJECT_ID == 0) {
|
|
69
|
-
|
|
71
|
+
// Check if the publisher already exists by scanning existing project IDs.
|
|
72
|
+
uint256 _existingCount = core.projects.count();
|
|
73
|
+
bool _found;
|
|
74
|
+
for (uint256 _candidateId = 1; _candidateId <= _existingCount; _candidateId++) {
|
|
75
|
+
(, bool _exists) = _isDeployed({
|
|
76
|
+
salt: PUBLISHER_SALT,
|
|
77
|
+
creationCode: type(CTPublisher).creationCode,
|
|
78
|
+
arguments: abi.encode(core.directory, core.permissions, _candidateId, TRUSTED_FORWARDER)
|
|
79
|
+
});
|
|
80
|
+
if (_exists) {
|
|
81
|
+
FEE_PROJECT_ID = _candidateId;
|
|
82
|
+
_found = true;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (!_found) {
|
|
87
|
+
FEE_PROJECT_ID = core.projects.createFor(safeAddress());
|
|
88
|
+
}
|
|
70
89
|
}
|
|
71
90
|
|
|
72
91
|
CTPublisher publisher;
|
package/src/CTDeployer.sol
CHANGED
|
@@ -225,9 +225,12 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
225
225
|
//*********************************************************************//
|
|
226
226
|
|
|
227
227
|
/// @notice Claim ownership of the collection.
|
|
228
|
-
/// @dev
|
|
229
|
-
///
|
|
230
|
-
///
|
|
228
|
+
/// @dev Two-step ownership transfer process:
|
|
229
|
+
/// Step 1 (this function): Transfers hook ownership to the project via `transferOwnershipToProject()`.
|
|
230
|
+
/// After this call, `hook.owner()` resolves dynamically through `PROJECTS.ownerOf(projectId)`.
|
|
231
|
+
/// Step 2 (caller must do separately): The project owner grants CTPublisher the `ADJUST_721_TIERS` permission
|
|
232
|
+
/// for the project so that `mintFrom()` continues to work.
|
|
233
|
+
/// Without the Step 2 permission grant, all subsequent posts will revert. This cannot be done atomically here
|
|
231
234
|
/// because after transferring ownership to the project, this contract no longer has authority to set permissions
|
|
232
235
|
/// on the project's behalf.
|
|
233
236
|
/// @param hook The hook to claim ownership of.
|
|
@@ -283,7 +286,6 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
283
286
|
tiersConfig: JB721InitTiersConfig({
|
|
284
287
|
tiers: new JB721TierConfig[](0), currency: JBCurrencyIds.ETH, decimals: 18
|
|
285
288
|
}),
|
|
286
|
-
reserveBeneficiary: address(0),
|
|
287
289
|
flags: JB721TiersHookFlags({
|
|
288
290
|
noNewTiersWithReserves: false,
|
|
289
291
|
noNewTiersWithVotes: false,
|
|
@@ -337,9 +339,10 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
337
339
|
PROJECTS.transferFrom({from: address(this), to: owner, tokenId: projectId});
|
|
338
340
|
|
|
339
341
|
// Set permission for the project's owner to do all the NFT things.
|
|
340
|
-
// These permissions are granted from CTDeployer (address(this))
|
|
341
|
-
//
|
|
342
|
-
//
|
|
342
|
+
// These permissions are granted from CTDeployer (address(this)) to the initial owner.
|
|
343
|
+
// The hook checks permissions against hook.owner(), which after claimCollectionOwnershipOf() resolves
|
|
344
|
+
// dynamically via PROJECTS.ownerOf(projectId). Before claiming, CTDeployer is the static hook owner,
|
|
345
|
+
// so these permissions allow the project owner to manage tiers through CTDeployer.
|
|
343
346
|
uint8[] memory permissionIds = new uint8[](4);
|
|
344
347
|
permissionIds[0] = JBPermissionIds.ADJUST_721_TIERS;
|
|
345
348
|
permissionIds[1] = JBPermissionIds.SET_721_METADATA;
|
|
@@ -19,6 +19,7 @@ import {CTAllowedPost} from "../../src/structs/CTAllowedPost.sol";
|
|
|
19
19
|
import {CTPost} from "../../src/structs/CTPost.sol";
|
|
20
20
|
|
|
21
21
|
contract MockPermissions is IJBPermissions {
|
|
22
|
+
// forge-lint: disable-next-line(mixed-case-function)
|
|
22
23
|
function WILDCARD_PROJECT_ID() external pure returns (uint256) {
|
|
23
24
|
return 0;
|
|
24
25
|
}
|
|
@@ -136,8 +137,11 @@ contract FeeTerminalRecorder {
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
contract ReentrantProjectTerminal {
|
|
140
|
+
// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
139
141
|
CTPublisher public immutable publisher;
|
|
142
|
+
// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
140
143
|
IJB721TiersHook public immutable hook;
|
|
144
|
+
// forge-lint: disable-next-line(screaming-snake-case-immutable)
|
|
141
145
|
address public immutable attackerFeeBeneficiary;
|
|
142
146
|
bool internal entered;
|
|
143
147
|
|
|
@@ -182,7 +186,7 @@ contract ReentrantProjectTerminal {
|
|
|
182
186
|
receive() external payable {}
|
|
183
187
|
}
|
|
184
188
|
|
|
185
|
-
contract
|
|
189
|
+
contract FeeBeneficiaryReentrancyTest is Test {
|
|
186
190
|
MockPermissions permissions;
|
|
187
191
|
MockDirectory directory;
|
|
188
192
|
MockStore store;
|