@croptop/core-v6 0.0.48 → 0.0.50

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@croptop/core-v6",
3
- "version": "0.0.48",
3
+ "version": "0.0.50",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -29,17 +29,17 @@
29
29
  "artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'croptop-core-v6'"
30
30
  },
31
31
  "dependencies": {
32
- "@bananapus/721-hook-v6": "^0.0.51",
33
- "@bananapus/core-v6": "^0.0.54",
34
- "@bananapus/ownable-v6": "^0.0.25",
32
+ "@bananapus/721-hook-v6": "^0.0.52",
33
+ "@bananapus/core-v6": "^0.0.55",
34
+ "@bananapus/ownable-v6": "^0.0.26",
35
35
  "@bananapus/permission-ids-v6": "^0.0.25",
36
- "@bananapus/router-terminal-v6": "^0.0.44",
37
- "@bananapus/suckers-v6": "^0.0.47",
36
+ "@bananapus/router-terminal-v6": "^0.0.45",
37
+ "@bananapus/suckers-v6": "^0.0.48",
38
38
  "@openzeppelin/contracts": "5.6.1",
39
- "@rev-net/core-v6": "^0.0.56"
39
+ "@rev-net/core-v6": "^0.0.58"
40
40
  },
41
41
  "devDependencies": {
42
- "@bananapus/address-registry-v6": "^0.0.25",
42
+ "@bananapus/address-registry-v6": "^0.0.26",
43
43
  "@sphinx-labs/plugins": "0.33.3"
44
44
  }
45
45
  }
package/remappings.txt CHANGED
@@ -1 +1,2 @@
1
1
  forge-std/=lib/forge-std/src/
2
+ @croptop/core-v6/=./
@@ -61,50 +61,29 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
61
61
  /// @notice tracks the deployment of the router terminal.
62
62
  RouterTerminalDeployment routerTerminal;
63
63
 
64
- // @notice set this to a non-zero value to re-use an existing projectID. Having it set to 0 will deploy a new
65
- // fee_project.
66
- // forge-lint: disable-next-line(mixed-case-variable)
67
- uint256 FEE_PROJECT_ID;
68
-
69
- // forge-lint: disable-next-line(mixed-case-variable)
70
- uint32 PREMINT_CHAIN_ID = 1;
71
- // forge-lint: disable-next-line(mixed-case-variable)
72
- string NAME = "Croptop Publishing Network";
73
- // forge-lint: disable-next-line(mixed-case-variable)
74
- string SYMBOL = "CPN";
75
- // forge-lint: disable-next-line(mixed-case-variable)
76
- string PROJECT_URI = "ipfs://QmUAFevoMn1iqSEQR8LogQYRxm39TNxQTPYnuLuq5BmfEi";
77
- // forge-lint: disable-next-line(mixed-case-variable)
78
- uint32 NATIVE_CURRENCY = uint32(uint160(JBConstants.NATIVE_TOKEN));
79
- // forge-lint: disable-next-line(mixed-case-variable)
80
- uint32 ETH_CURRENCY = JBCurrencyIds.ETH;
81
- // forge-lint: disable-next-line(mixed-case-variable)
82
- uint8 DECIMALS = 18;
83
- // forge-lint: disable-next-line(mixed-case-variable)
84
- uint256 DECIMAL_MULTIPLIER = 10 ** DECIMALS;
85
- // forge-lint: disable-next-line(mixed-case-variable)
86
- bytes32 SUCKER_SALT = "_CPN_SUCKERV6__";
87
- // forge-lint: disable-next-line(mixed-case-variable)
88
- bytes32 ERC20_SALT = "_CPN_ERC20_SALTV6__";
89
- // forge-lint: disable-next-line(mixed-case-variable)
90
- bytes32 HOOK_SALT = "_CPN_HOOK_SALTV6__";
91
- // forge-lint: disable-next-line(mixed-case-variable)
92
- address OPERATOR;
93
- // forge-lint: disable-next-line(mixed-case-variable)
94
- address TRUSTED_FORWARDER;
95
- // forge-lint: disable-next-line(mixed-case-variable)
96
- uint48 CPN_START_TIME = 1_740_089_444;
97
- // forge-lint: disable-next-line(mixed-case-variable)
98
- uint104 CPN_MAINNET_AUTO_ISSUANCE_ = 250_003_875_000_000_000_000_000;
99
- // forge-lint: disable-next-line(mixed-case-variable)
100
- uint104 CPN_OP_AUTO_ISSUANCE_ = 844_894_881_600_000_000_000;
101
- // forge-lint: disable-next-line(mixed-case-variable)
102
- uint104 CPN_BASE_AUTO_ISSUANCE_ = 844_894_881_600_000_000_000;
103
- // forge-lint: disable-next-line(mixed-case-variable)
104
- uint104 CPN_ARB_AUTO_ISSUANCE_ = 3_844_000_000_000_000_000;
64
+ /// @notice The fee project ID configured by the Croptop publisher.
65
+ uint256 private feeProjectId;
66
+ uint32 private constant _PREMINT_CHAIN_ID = 1;
67
+ string private constant _NAME = "Croptop Publishing Network";
68
+ string private constant _SYMBOL = "CPN";
69
+ string private constant _PROJECT_URI = "ipfs://QmUAFevoMn1iqSEQR8LogQYRxm39TNxQTPYnuLuq5BmfEi";
70
+ uint32 private constant _NATIVE_CURRENCY = uint32(uint160(JBConstants.NATIVE_TOKEN));
71
+ uint32 private constant _ETH_CURRENCY = JBCurrencyIds.ETH;
72
+ uint8 private constant _DECIMALS = 18;
73
+ uint256 private constant _DECIMAL_MULTIPLIER = 10 ** _DECIMALS;
74
+ bytes32 private constant _SUCKER_SALT = "_CPN_SUCKERV6__";
75
+ bytes32 private constant _ERC20_SALT = "_CPN_ERC20_SALTV6__";
76
+ bytes32 private constant _HOOK_SALT = "_CPN_HOOK_SALTV6__";
77
+ address private operator;
78
+ address private trustedForwarder;
79
+ uint48 private constant _CPN_START_TIME = 1_740_089_444;
80
+ uint104 private constant _CPN_MAINNET_AUTO_ISSUANCE = 250_003_875_000_000_000_000_000;
81
+ uint104 private constant _CPN_OP_AUTO_ISSUANCE = 844_894_881_600_000_000_000;
82
+ uint104 private constant _CPN_BASE_AUTO_ISSUANCE = 844_894_881_600_000_000_000;
83
+ uint104 private constant _CPN_ARB_AUTO_ISSUANCE = 3_844_000_000_000_000_000;
105
84
 
106
85
  function configureSphinx() public override {
107
- // TODO: Update to contain croptop devs.
86
+ // Safe owners and threshold are resolved by the Sphinx project config.
108
87
  sphinxConfig.projectName = "croptop-core-v6";
109
88
  sphinxConfig.mainnets = ["ethereum", "optimism", "base", "arbitrum"];
110
89
  sphinxConfig.testnets = ["ethereum_sepolia", "optimism_sepolia", "base_sepolia", "arbitrum_sepolia"];
@@ -139,14 +118,14 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
139
118
  );
140
119
 
141
120
  // We do a quick sanity check to make sure revnet and croptop use the same juicebox core contracts.
142
- require(revnet.basic_deployer.DIRECTORY() == croptop.publisher.DIRECTORY());
121
+ require(revnet.basicDeployer.DIRECTORY() == croptop.publisher.DIRECTORY());
143
122
 
144
123
  // Set the operator address to be the multisig.
145
- OPERATOR = safeAddress();
146
- TRUSTED_FORWARDER = core.controller.trustedForwarder();
124
+ operator = safeAddress();
125
+ trustedForwarder = core.controller.trustedForwarder();
147
126
 
148
127
  // Get the fee project id from the croptop deployment.
149
- FEE_PROJECT_ID = croptop.publisher.FEE_PROJECT_ID();
128
+ feeProjectId = croptop.publisher.FEE_PROJECT_ID();
150
129
 
151
130
  // Check if there should be a new fee project created.
152
131
  // Perform the deployment transactions.
@@ -159,7 +138,7 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
159
138
 
160
139
  // Accept the chain's native currency through the multi terminal.
161
140
  accountingContextsToAccept[0] =
162
- JBAccountingContext({token: JBConstants.NATIVE_TOKEN, decimals: DECIMALS, currency: NATIVE_CURRENCY});
141
+ JBAccountingContext({token: JBConstants.NATIVE_TOKEN, decimals: _DECIMALS, currency: _NATIVE_CURRENCY});
163
142
 
164
143
  // The terminals that the project will accept funds through.
165
144
  JBTerminalConfig[] memory terminalConfigurations = new JBTerminalConfig[](2);
@@ -171,16 +150,16 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
171
150
  });
172
151
 
173
152
  REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](4);
174
- issuanceConfs[0] = REVAutoIssuance({chainId: 1, count: CPN_MAINNET_AUTO_ISSUANCE_, beneficiary: OPERATOR});
175
- issuanceConfs[1] = REVAutoIssuance({chainId: 10, count: CPN_OP_AUTO_ISSUANCE_, beneficiary: OPERATOR});
176
- issuanceConfs[2] = REVAutoIssuance({chainId: 8453, count: CPN_BASE_AUTO_ISSUANCE_, beneficiary: OPERATOR});
177
- issuanceConfs[3] = REVAutoIssuance({chainId: 42_161, count: CPN_ARB_AUTO_ISSUANCE_, beneficiary: OPERATOR});
153
+ issuanceConfs[0] = REVAutoIssuance({chainId: 1, count: _CPN_MAINNET_AUTO_ISSUANCE, beneficiary: operator});
154
+ issuanceConfs[1] = REVAutoIssuance({chainId: 10, count: _CPN_OP_AUTO_ISSUANCE, beneficiary: operator});
155
+ issuanceConfs[2] = REVAutoIssuance({chainId: 8453, count: _CPN_BASE_AUTO_ISSUANCE, beneficiary: operator});
156
+ issuanceConfs[3] = REVAutoIssuance({chainId: 42_161, count: _CPN_ARB_AUTO_ISSUANCE, beneficiary: operator});
178
157
 
179
158
  JBSplit[] memory splits = new JBSplit[](1);
180
159
  splits[0] = JBSplit({
181
160
  percent: JBConstants.SPLITS_TOTAL_PERCENT,
182
161
  projectId: 0,
183
- beneficiary: payable(OPERATOR),
162
+ beneficiary: payable(operator),
184
163
  preferAddToBalance: false,
185
164
  lockedUntil: 0,
186
165
  hook: IJBSplitHook(address(0))
@@ -189,12 +168,12 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
189
168
  // The project's revnet stage configurations.
190
169
  REVStageConfig[] memory stageConfigurations = new REVStageConfig[](3);
191
170
  stageConfigurations[0] = REVStageConfig({
192
- startsAtOrAfter: CPN_START_TIME,
171
+ startsAtOrAfter: _CPN_START_TIME,
193
172
  autoIssuances: issuanceConfs,
194
173
  splitPercent: 3800, // 38%
195
174
  splits: splits,
196
175
  // forge-lint: disable-next-line(unsafe-typecast)
197
- initialIssuance: uint112(10_000 * DECIMAL_MULTIPLIER),
176
+ initialIssuance: uint112(10_000 * _DECIMAL_MULTIPLIER),
198
177
  issuanceCutFrequency: 120 days,
199
178
  issuanceCutPercent: 380_000_000, // 38%
200
179
  cashOutTaxRate: 1000, // 0.1
@@ -227,9 +206,9 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
227
206
 
228
207
  // The project's revnet configuration
229
208
  REVConfig memory revnetConfiguration = REVConfig({
230
- description: REVDescription({name: NAME, ticker: SYMBOL, uri: PROJECT_URI, salt: ERC20_SALT}),
231
- baseCurrency: ETH_CURRENCY,
232
- operator: OPERATOR,
209
+ description: REVDescription({name: _NAME, ticker: _SYMBOL, uri: _PROJECT_URI, salt: _ERC20_SALT}),
210
+ baseCurrency: _ETH_CURRENCY,
211
+ operator: operator,
233
212
  scopeCashOutsToLocalBalances: false,
234
213
  stageConfigurations: stageConfigurations
235
214
  });
@@ -276,14 +255,14 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
276
255
  }
277
256
  // Specify all sucker deployments.
278
257
  suckerDeploymentConfiguration =
279
- REVSuckerDeploymentConfig({deployerConfigurations: suckerDeployerConfigurations, salt: SUCKER_SALT});
258
+ REVSuckerDeploymentConfig({deployerConfigurations: suckerDeployerConfigurations, salt: _SUCKER_SALT});
280
259
  }
281
260
 
282
261
  // The project's allowed croptop posts.
283
262
  REVCroptopAllowedPost[] memory allowedPosts = new REVCroptopAllowedPost[](5);
284
263
  allowedPosts[0] = REVCroptopAllowedPost({
285
264
  category: 0,
286
- minimumPrice: uint104(10 ** (DECIMALS - 5)),
265
+ minimumPrice: uint104(10 ** (_DECIMALS - 5)),
287
266
  minimumTotalSupply: 10_000,
288
267
  maximumTotalSupply: 999_999_999,
289
268
  maximumSplitPercent: 0,
@@ -291,7 +270,7 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
291
270
  });
292
271
  allowedPosts[1] = REVCroptopAllowedPost({
293
272
  category: 1,
294
- minimumPrice: uint104(10 ** (DECIMALS - 3)),
273
+ minimumPrice: uint104(10 ** (_DECIMALS - 3)),
295
274
  minimumTotalSupply: 10_000,
296
275
  maximumTotalSupply: 999_999_999,
297
276
  maximumSplitPercent: 0,
@@ -299,7 +278,7 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
299
278
  });
300
279
  allowedPosts[2] = REVCroptopAllowedPost({
301
280
  category: 2,
302
- minimumPrice: uint104(10 ** (DECIMALS - 1)),
281
+ minimumPrice: uint104(10 ** (_DECIMALS - 1)),
303
282
  minimumTotalSupply: 100,
304
283
  maximumTotalSupply: 999_999_999,
305
284
  maximumSplitPercent: 0,
@@ -307,7 +286,7 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
307
286
  });
308
287
  allowedPosts[3] = REVCroptopAllowedPost({
309
288
  category: 3,
310
- minimumPrice: uint104(10 ** DECIMALS),
289
+ minimumPrice: uint104(10 ** _DECIMALS),
311
290
  minimumTotalSupply: 10,
312
291
  maximumTotalSupply: 999_999_999,
313
292
  maximumSplitPercent: 0,
@@ -315,7 +294,7 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
315
294
  });
316
295
  allowedPosts[4] = REVCroptopAllowedPost({
317
296
  category: 4,
318
- minimumPrice: uint104(10 ** (DECIMALS + 2)),
297
+ minimumPrice: uint104(10 ** (_DECIMALS + 2)),
319
298
  minimumTotalSupply: 10,
320
299
  maximumTotalSupply: 999_999_999,
321
300
  maximumSplitPercent: 0,
@@ -328,13 +307,13 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
328
307
  suckerDeploymentConfiguration: suckerDeploymentConfiguration,
329
308
  hookConfiguration: REVDeploy721TiersHookConfig({
330
309
  baseline721HookConfiguration: REVBaseline721HookConfig({
331
- name: NAME,
332
- symbol: SYMBOL,
310
+ name: _NAME,
311
+ symbol: _SYMBOL,
333
312
  baseUri: "ipfs://",
334
313
  tokenUriResolver: IJB721TokenUriResolver(address(0)),
335
314
  contractUri: "",
336
315
  tiersConfig: JB721InitTiersConfig({
337
- tiers: new JB721TierConfig[](0), currency: ETH_CURRENCY, decimals: DECIMALS
316
+ tiers: new JB721TierConfig[](0), currency: _ETH_CURRENCY, decimals: _DECIMALS
338
317
  }),
339
318
  flags: REV721TiersHookFlags({
340
319
  noNewTiersWithReserves: false,
@@ -343,7 +322,7 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
343
322
  preventOverspending: false
344
323
  })
345
324
  }),
346
- salt: HOOK_SALT,
325
+ salt: _HOOK_SALT,
347
326
  preventOperatorAdjustingTiers: false,
348
327
  preventOperatorUpdatingMetadata: false,
349
328
  preventOperatorMinting: false,
@@ -357,14 +336,14 @@ contract ConfigureFeeProjectScript is Script, Sphinx {
357
336
  FeeProjectConfig memory feeProjectConfig = getCroptopRevnetConfig();
358
337
 
359
338
  // Only deploy if the project hasn't already been configured (restart-safe).
360
- if (address(core.directory.controllerOf(FEE_PROJECT_ID)) == address(0)) {
339
+ if (address(core.directory.controllerOf(feeProjectId)) == address(0)) {
361
340
  // Approve the basic deployer to configure the project and transfer it.
362
- core.projects.approve({to: address(revnet.basic_deployer), tokenId: FEE_PROJECT_ID});
341
+ core.projects.approve({to: address(revnet.basicDeployer), tokenId: feeProjectId});
363
342
 
364
343
  // Deploy the NANA fee project.
365
- revnet.basic_deployer
344
+ revnet.basicDeployer
366
345
  .deployFor({
367
- revnetId: FEE_PROJECT_ID,
346
+ revnetId: feeProjectId,
368
347
  configuration: feeProjectConfig.configuration,
369
348
  terminalConfigurations: feeProjectConfig.terminalConfigurations,
370
349
  suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration,
@@ -20,20 +20,14 @@ contract DeployScript is Script, Sphinx {
20
20
  /// @notice tracks the deployment of the sucker contracts for the chain we are deploying to.
21
21
  SuckerDeployment suckers;
22
22
 
23
- // @notice set this to a non-zero value to re-use an existing projectID. Having it set to 0 will deploy a new
24
- // fee_project.
25
- // forge-lint: disable-next-line(mixed-case-variable)
26
- uint256 FEE_PROJECT_ID = 0;
23
+ /// @notice Set this to a non-zero value to reuse an existing fee project. Leaving it as 0 deploys a new one.
24
+ uint256 private feeProjectId = 0;
27
25
 
28
26
  /// @notice the salts that are used to deploy the contracts.
29
- // forge-lint: disable-next-line(mixed-case-variable)
30
- bytes32 PUBLISHER_SALT = "_PUBLISHER_SALTV6_";
31
- // forge-lint: disable-next-line(mixed-case-variable)
32
- bytes32 DEPLOYER_SALT = "_DEPLOYER_SALTV6_";
33
- // forge-lint: disable-next-line(mixed-case-variable)
34
- bytes32 PROJECT_OWNER_SALT = "_PROJECT_OWNER_SALTV6_";
35
- // forge-lint: disable-next-line(mixed-case-variable)
36
- address TRUSTED_FORWARDER;
27
+ bytes32 private constant _PUBLISHER_SALT = "_PUBLISHER_SALTV6_";
28
+ bytes32 private constant _DEPLOYER_SALT = "_DEPLOYER_SALTV6_";
29
+ bytes32 private constant _PROJECT_OWNER_SALT = "_PROJECT_OWNER_SALTV6_";
30
+ address private trustedForwarder;
37
31
 
38
32
  function configureSphinx() public override {
39
33
  sphinxConfig.projectName = "croptop-core-v6";
@@ -57,7 +51,7 @@ contract DeployScript is Script, Sphinx {
57
51
  );
58
52
 
59
53
  // We use the same trusted forwarder as the core deployment.
60
- TRUSTED_FORWARDER = core.controller.trustedForwarder();
54
+ trustedForwarder = core.controller.trustedForwarder();
61
55
 
62
56
  // Perform the deployment transactions.
63
57
  deploy();
@@ -67,24 +61,24 @@ contract DeployScript is Script, Sphinx {
67
61
  // Canonical Croptop deployments must bind fees to an explicit fee project. Autodiscovering the first
68
62
  // matching publisher by scanning project IDs is unsafe because a preexisting publisher can pin fees to
69
63
  // the wrong project forever.
70
- require(FEE_PROJECT_ID != 0, "explicit fee project id required");
64
+ require(feeProjectId != 0, "explicit fee project id required");
71
65
 
72
66
  CTPublisher publisher;
73
67
  {
74
68
  // Perform the check for the publisher.
75
69
  (address _publisher, bool _publisherIsDeployed) = _isDeployed({
76
- salt: PUBLISHER_SALT,
70
+ salt: _PUBLISHER_SALT,
77
71
  creationCode: type(CTPublisher).creationCode,
78
- arguments: abi.encode(core.directory, core.permissions, FEE_PROJECT_ID, TRUSTED_FORWARDER)
72
+ arguments: abi.encode(core.directory, core.permissions, feeProjectId, trustedForwarder)
79
73
  });
80
74
 
81
75
  // Deploy it if it has not been deployed yet.
82
76
  publisher = !_publisherIsDeployed
83
- ? new CTPublisher{salt: PUBLISHER_SALT}({
77
+ ? new CTPublisher{salt: _PUBLISHER_SALT}({
84
78
  directory: core.directory,
85
79
  permissions: core.permissions,
86
- feeProjectId: FEE_PROJECT_ID,
87
- trustedForwarder: TRUSTED_FORWARDER
80
+ feeProjectId: feeProjectId,
81
+ trustedForwarder: trustedForwarder
88
82
  })
89
83
  : CTPublisher(_publisher);
90
84
  }
@@ -93,22 +87,22 @@ contract DeployScript is Script, Sphinx {
93
87
  {
94
88
  // Perform the check for the publisher.
95
89
  (address _deployer, bool _deployerIsDeployed) = _isDeployed({
96
- salt: DEPLOYER_SALT,
90
+ salt: _DEPLOYER_SALT,
97
91
  creationCode: type(CTDeployer).creationCode,
98
92
  arguments: abi.encode(
99
- core.permissions, core.projects, hook.hook_deployer, publisher, suckers.registry, TRUSTED_FORWARDER
93
+ core.permissions, core.projects, hook.hookDeployer, publisher, suckers.registry, trustedForwarder
100
94
  )
101
95
  });
102
96
 
103
97
  // Deploy it if it has not been deployed yet.
104
98
  deployer = !_deployerIsDeployed
105
- ? new CTDeployer{salt: DEPLOYER_SALT}({
99
+ ? new CTDeployer{salt: _DEPLOYER_SALT}({
106
100
  permissions: core.permissions,
107
101
  projects: core.projects,
108
- deployer: hook.hook_deployer,
102
+ deployer: hook.hookDeployer,
109
103
  publisher: publisher,
110
104
  suckerRegistry: suckers.registry,
111
- trustedForwarder: TRUSTED_FORWARDER
105
+ trustedForwarder: trustedForwarder
112
106
  })
113
107
  : CTDeployer(_deployer);
114
108
  }
@@ -117,14 +111,14 @@ contract DeployScript is Script, Sphinx {
117
111
  {
118
112
  // Perform the check for the publisher.
119
113
  (address _owner, bool _ownerIsDeployed) = _isDeployed({
120
- salt: PROJECT_OWNER_SALT,
114
+ salt: _PROJECT_OWNER_SALT,
121
115
  creationCode: type(CTProjectOwner).creationCode,
122
116
  arguments: abi.encode(core.permissions, core.projects, publisher)
123
117
  });
124
118
 
125
119
  // Deploy it if it has not been deployed yet.
126
120
  owner = !_ownerIsDeployed
127
- ? new CTProjectOwner{salt: PROJECT_OWNER_SALT}({
121
+ ? new CTProjectOwner{salt: _PROJECT_OWNER_SALT}({
128
122
  permissions: core.permissions, projects: core.projects, publisher: publisher
129
123
  })
130
124
  : CTProjectOwner(_owner);
@@ -13,8 +13,7 @@ import {CTProjectOwner} from "../../src/CTProjectOwner.sol";
13
13
  struct CroptopDeployment {
14
14
  CTPublisher publisher;
15
15
  CTDeployer deployer;
16
- // forge-lint: disable-next-line(mixed-case-variable)
17
- CTProjectOwner project_owner;
16
+ CTProjectOwner projectOwner;
18
17
  }
19
18
 
20
19
  library CroptopDeploymentLib {
@@ -24,17 +23,16 @@ library CroptopDeploymentLib {
24
23
  Vm internal constant vm = Vm(VM_ADDRESS);
25
24
 
26
25
  function getDeployment(string memory path) internal returns (CroptopDeployment memory deployment) {
27
- // get chainId for which we need to get the deployment.
26
+ // Match the current chain ID to the Sphinx network name used in deployment artifacts.
28
27
  uint256 chainId = block.chainid;
29
28
 
30
- // Deploy to get the constants.
31
- // TODO: get constants without deploy.
29
+ // `SphinxConstants` exposes Sphinx's supported chain ID to network name mapping.
32
30
  SphinxConstants sphinxConstants = new SphinxConstants();
33
31
  NetworkInfo[] memory networks = sphinxConstants.getNetworkInfoArray();
34
32
 
35
33
  for (uint256 _i; _i < networks.length; _i++) {
36
34
  if (networks[_i].chainId == chainId) {
37
- return getDeployment(path, networks[_i].name);
35
+ return getDeployment({path: path, networkName: networks[_i].name});
38
36
  }
39
37
  }
40
38
 
@@ -43,8 +41,7 @@ library CroptopDeploymentLib {
43
41
 
44
42
  function getDeployment(
45
43
  string memory path,
46
- // forge-lint: disable-next-line(mixed-case-variable)
47
- string memory network_name
44
+ string memory networkName
48
45
  )
49
46
  internal
50
47
  view
@@ -52,17 +49,17 @@ library CroptopDeploymentLib {
52
49
  {
53
50
  deployment.publisher = CTPublisher(
54
51
  _getDeploymentAddress({
55
- path: path, project_name: "croptop-core-v6", network_name: network_name, contractName: "CTPublisher"
52
+ path: path, projectName: "croptop-core-v6", networkName: networkName, contractName: "CTPublisher"
56
53
  })
57
54
  );
58
55
  deployment.deployer = CTDeployer(
59
56
  _getDeploymentAddress({
60
- path: path, project_name: "croptop-core-v6", network_name: network_name, contractName: "CTDeployer"
57
+ path: path, projectName: "croptop-core-v6", networkName: networkName, contractName: "CTDeployer"
61
58
  })
62
59
  );
63
- deployment.project_owner = CTProjectOwner(
60
+ deployment.projectOwner = CTProjectOwner(
64
61
  _getDeploymentAddress({
65
- path: path, project_name: "croptop-core-v6", network_name: network_name, contractName: "CTProjectOwner"
62
+ path: path, projectName: "croptop-core-v6", networkName: networkName, contractName: "CTProjectOwner"
66
63
  })
67
64
  );
68
65
  }
@@ -74,10 +71,8 @@ library CroptopDeploymentLib {
74
71
  /// @return The address of the contract.
75
72
  function _getDeploymentAddress(
76
73
  string memory path,
77
- // forge-lint: disable-next-line(mixed-case-variable)
78
- string memory project_name,
79
- // forge-lint: disable-next-line(mixed-case-variable)
80
- string memory network_name,
74
+ string memory projectName,
75
+ string memory networkName,
81
76
  string memory contractName
82
77
  )
83
78
  internal
@@ -86,7 +81,7 @@ library CroptopDeploymentLib {
86
81
  {
87
82
  string memory deploymentJson =
88
83
  // forge-lint: disable-next-line(unsafe-cheatcode)
89
- vm.readFile(string.concat(path, project_name, "/", network_name, "/", contractName, ".json"));
84
+ vm.readFile(string.concat(path, projectName, "/", networkName, "/", contractName, ".json"));
90
85
  return stdJson.readAddress({json: deploymentJson, key: ".address"});
91
86
  }
92
87
  }
@@ -131,7 +131,7 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
131
131
  /// @param hook The hook to claim ownership of.
132
132
  function claimCollectionOwnershipOf(IJB721TiersHook hook) external override {
133
133
  // Get the project ID of the hook.
134
- uint256 projectId = hook.PROJECT_ID();
134
+ uint256 projectId = hook.projectId();
135
135
 
136
136
  // Keep a reference to the caller.
137
137
  address caller = _msgSender();
@@ -31,8 +31,8 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
31
31
  // --------------------------- custom errors ------------------------- //
32
32
  //*********************************************************************//
33
33
 
34
- error CTPublisher_DuplicatePost(bytes32 encodedIPFSUri);
35
- error CTPublisher_EmptyEncodedIPFSUri(uint256 postIndex);
34
+ error CTPublisher_DuplicatePost(bytes32 encodedIpfsUri);
35
+ error CTPublisher_EmptyEncodedIpfsUri(uint256 postIndex);
36
36
  error CTPublisher_InsufficientEthSent(uint256 expected, uint256 sent);
37
37
  error CTPublisher_MaxTotalSupplyLessThanMin(uint256 min, uint256 max);
38
38
  error CTPublisher_NotInAllowList(address addr, address[] allowedAddresses);
@@ -71,8 +71,8 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
71
71
 
72
72
  /// @notice The ID of the tier that an IPFS metadata has been saved to.
73
73
  /// @custom:param hook The hook for which the tier ID applies.
74
- /// @custom:param encodedIPFSUri The IPFS URI.
75
- mapping(address hook => mapping(bytes32 encodedIPFSUri => uint256)) public override tierIdForEncodedIPFSUriOf;
74
+ /// @custom:param encodedIpfsUri The IPFS URI.
75
+ mapping(address hook => mapping(bytes32 encodedIpfsUri => uint256)) public override tierIdForEncodedIpfsUriOf;
76
76
 
77
77
  //*********************************************************************//
78
78
  // --------------------- internal stored properties ------------------ //
@@ -136,7 +136,7 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
136
136
  // Enforce permissions.
137
137
  _requirePermissionFrom({
138
138
  account: JBOwnable(allowedPost.hook).owner(),
139
- projectId: IJB721TiersHook(allowedPost.hook).PROJECT_ID(),
139
+ projectId: IJB721TiersHook(allowedPost.hook).projectId(),
140
140
  permissionId: JBPermissionIds.ADJUST_721_TIERS
141
141
  });
142
142
 
@@ -214,7 +214,7 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
214
214
  bytes memory mintMetadata;
215
215
 
216
216
  // Keep a reference to the project's ID.
217
- uint256 projectId = hook.PROJECT_ID();
217
+ uint256 projectId = hook.projectId();
218
218
 
219
219
  {
220
220
  // Setup the posts.
@@ -337,27 +337,27 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
337
337
  /// In that case, the store's tierOf call will return a tier with default/empty values. Callers should check
338
338
  /// the returned tier's initialSupply or other fields to confirm the tier still exists.
339
339
  /// @param hook The hook from which to get tiers.
340
- /// @param encodedIPFSUris The URIs to get tiers of.
340
+ /// @param encodedIpfsUris The URIs to get tiers of.
341
341
  /// @return tiers The tiers that correspond to the provided encoded IPFS URIs. If there's no tier yet, an empty tier
342
342
  /// is returned.
343
343
  function tiersFor(
344
344
  address hook,
345
- bytes32[] memory encodedIPFSUris
345
+ bytes32[] memory encodedIpfsUris
346
346
  )
347
347
  external
348
348
  view
349
349
  override
350
350
  returns (JB721Tier[] memory tiers)
351
351
  {
352
- uint256 numberOfEncodedIPFSUris = encodedIPFSUris.length;
352
+ uint256 numberOfEncodedIpfsUris = encodedIpfsUris.length;
353
353
 
354
354
  // Initialize the tier array being returned.
355
- tiers = new JB721Tier[](numberOfEncodedIPFSUris);
355
+ tiers = new JB721Tier[](numberOfEncodedIpfsUris);
356
356
 
357
357
  // Get the tier for each provided encoded IPFS URI.
358
- for (uint256 i; i < numberOfEncodedIPFSUris;) {
358
+ for (uint256 i; i < numberOfEncodedIpfsUris;) {
359
359
  // Check if there's a tier ID stored for the encoded IPFS URI.
360
- uint256 tierId = tierIdForEncodedIPFSUriOf[hook][encodedIPFSUris[i]];
360
+ uint256 tierId = tierIdForEncodedIpfsUriOf[hook][encodedIpfsUris[i]];
361
361
 
362
362
  // If there's a tier ID stored, resolve it.
363
363
  if (tierId != 0) {
@@ -457,16 +457,16 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
457
457
  // Get the current post being iterated on.
458
458
  CTPost memory post = posts[i];
459
459
 
460
- // Make sure the post includes an encodedIPFSUri.
460
+ // Make sure the post includes an encodedIpfsUri.
461
461
  // forge-lint: disable-next-line(unsafe-typecast)
462
- if (post.encodedIPFSUri == bytes32("")) {
463
- revert CTPublisher_EmptyEncodedIPFSUri({postIndex: i});
462
+ if (post.encodedIpfsUri == bytes32("")) {
463
+ revert CTPublisher_EmptyEncodedIpfsUri({postIndex: i});
464
464
  }
465
465
 
466
- // Check for duplicate encodedIPFSUri within the same batch to prevent fee evasion.
466
+ // Check for duplicate encodedIpfsUri within the same batch to prevent fee evasion.
467
467
  for (uint256 j; j < i;) {
468
- if (posts[j].encodedIPFSUri == post.encodedIPFSUri) {
469
- revert CTPublisher_DuplicatePost({encodedIPFSUri: post.encodedIPFSUri});
468
+ if (posts[j].encodedIpfsUri == post.encodedIpfsUri) {
469
+ revert CTPublisher_DuplicatePost({encodedIpfsUri: post.encodedIpfsUri});
470
470
  }
471
471
  unchecked {
472
472
  ++j;
@@ -475,8 +475,8 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
475
475
 
476
476
  // Scoped section to prevent stack too deep.
477
477
  {
478
- // Check if there's an ID of a tier already minted for this encodedIPFSUri.
479
- uint256 tierId = tierIdForEncodedIPFSUriOf[address(hook)][post.encodedIPFSUri];
478
+ // Check if there's an ID of a tier already minted for this encodedIpfsUri.
479
+ uint256 tierId = tierIdForEncodedIpfsUriOf[address(hook)][post.encodedIpfsUri];
480
480
 
481
481
  if (tierId != 0) {
482
482
  // Validate the cached tier still exists and its URI still matches.
@@ -485,9 +485,11 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
485
485
  // mapping and fall through to create a new tier.
486
486
  JB721Tier memory cachedTier =
487
487
  store.tierOf({hook: address(hook), id: tierId, includeResolvedUri: false});
488
- if (store.isTierRemoved(address(hook), tierId) || cachedTier.encodedIPFSUri != post.encodedIPFSUri)
489
- {
490
- delete tierIdForEncodedIPFSUriOf[address(hook)][post.encodedIPFSUri];
488
+ if (
489
+ store.isTierRemoved({hook: address(hook), tierId: tierId})
490
+ || cachedTier.encodedIpfsUri != post.encodedIpfsUri
491
+ ) {
492
+ delete tierIdForEncodedIpfsUriOf[address(hook)][post.encodedIpfsUri];
491
493
  } else {
492
494
  tierIdsToMint[i] = tierId;
493
495
 
@@ -557,7 +559,7 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
557
559
  votingUnits: 0,
558
560
  reserveFrequency: 0,
559
561
  reserveBeneficiary: address(0),
560
- encodedIPFSUri: post.encodedIPFSUri,
562
+ encodedIpfsUri: post.encodedIpfsUri,
561
563
  category: post.category,
562
564
  discountPercent: 0,
563
565
  flags: JB721TierConfigFlags({
@@ -576,8 +578,8 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
576
578
  // Set the ID of the tier to mint.
577
579
  tierIdsToMint[i] = startingTierId + numberOfTiersBeingAdded++;
578
580
 
579
- // Save the encodedIPFSUri as minted.
580
- tierIdForEncodedIPFSUriOf[address(hook)][post.encodedIPFSUri] = tierIdsToMint[i];
581
+ // Save the encodedIpfsUri as minted.
582
+ tierIdForEncodedIpfsUriOf[address(hook)][post.encodedIpfsUri] = tierIdsToMint[i];
581
583
 
582
584
  // For new tiers, use the post's price for totalPrice accumulation.
583
585
  totalPrice += post.price;
@@ -71,17 +71,17 @@ interface ICTPublisher {
71
71
 
72
72
  /// @notice The tier ID that an IPFS metadata URI has been saved to for a given hook.
73
73
  /// @param hook The hook for which the tier ID applies.
74
- /// @param encodedIPFSUri The encoded IPFS URI to look up.
74
+ /// @param encodedIpfsUri The encoded IPFS URI to look up.
75
75
  /// @return The tier ID, or 0 if the URI has not been published.
76
76
  // forge-lint: disable-next-line(mixed-case-function)
77
- function tierIdForEncodedIPFSUriOf(address hook, bytes32 encodedIPFSUri) external view returns (uint256);
77
+ function tierIdForEncodedIpfsUriOf(address hook, bytes32 encodedIpfsUri) external view returns (uint256);
78
78
 
79
79
  /// @notice Get the tiers for the provided encoded IPFS URIs.
80
80
  /// @param hook The hook from which to get tiers.
81
- /// @param encodedIPFSUris The URIs to get tiers of.
81
+ /// @param encodedIpfsUris The URIs to get tiers of.
82
82
  /// @return tiers The tiers that correspond to the provided encoded IPFS URIs. Empty tiers are returned for URIs
83
83
  /// without a tier.
84
- function tiersFor(address hook, bytes32[] memory encodedIPFSUris) external view returns (JB721Tier[] memory tiers);
84
+ function tiersFor(address hook, bytes32[] memory encodedIpfsUris) external view returns (JB721Tier[] memory tiers);
85
85
 
86
86
  /// @notice Configure the allowed criteria for publishing new NFTs to a hook.
87
87
  /// @param allowedPosts An array of criteria for allowed posts.
@@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
4
4
  import {JBSplit} from "@bananapus/core-v6/src/structs/JBSplit.sol";
5
5
 
6
6
  /// @notice A post to be published.
7
- /// @custom:member encodedIPFSUri The encoded IPFS URI of the post to publish.
7
+ /// @custom:member encodedIpfsUri The encoded IPFS URI of the post to publish.
8
8
  /// @custom:member totalSupply The number of NFTs that should be made available, including the 1 that will be minted
9
9
  /// alongside this transaction.
10
10
  /// @custom:member price The price to pay for buying the post.
@@ -13,7 +13,7 @@ import {JBSplit} from "@bananapus/core-v6/src/structs/JBSplit.sol";
13
13
  /// JBConstants.SPLITS_TOTAL_PERCENT).
14
14
  /// @custom:member splits The splits to route funds to when this tier is minted.
15
15
  struct CTPost {
16
- bytes32 encodedIPFSUri;
16
+ bytes32 encodedIpfsUri;
17
17
  uint32 totalSupply;
18
18
  uint104 price;
19
19
  uint24 category;