@bananapus/core-v6 0.0.9 → 0.0.11
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/ADMINISTRATION.md +327 -0
- package/ARCHITECTURE.md +115 -0
- package/RISKS.md +68 -0
- package/SKILLS.md +5 -0
- package/STYLE_GUIDE.md +465 -0
- package/foundry.toml +1 -2
- package/package.json +2 -2
- package/src/JBChainlinkV3PriceFeed.sol +1 -5
- package/src/JBChainlinkV3SequencerPriceFeed.sol +1 -1
- package/src/JBController.sol +277 -277
- package/src/JBDeadline.sol +1 -1
- package/src/JBDirectory.sol +93 -93
- package/src/JBERC20.sol +43 -39
- package/src/JBFeelessAddresses.sol +12 -12
- package/src/JBFundAccessLimits.sol +82 -82
- package/src/JBMultiTerminal.sol +313 -313
- package/src/JBPermissions.sol +104 -100
- package/src/JBPrices.sol +68 -68
- package/src/JBProjects.sol +31 -31
- package/src/JBRulesets.sol +422 -422
- package/src/JBSplits.sol +116 -116
- package/src/JBTerminalStore.sol +651 -651
- package/src/JBTokens.sol +41 -41
- package/src/interfaces/IJBCashOutTerminal.sol +25 -7
- package/src/interfaces/IJBController.sol +78 -3
- package/src/interfaces/IJBDirectory.sol +25 -0
- package/src/interfaces/IJBFeeTerminal.sol +31 -0
- package/src/interfaces/IJBFeelessAddresses.sol +4 -0
- package/src/interfaces/IJBFundAccessLimits.sol +5 -0
- package/src/interfaces/IJBMigratable.sol +12 -8
- package/src/interfaces/IJBPayoutTerminal.sol +56 -9
- package/src/interfaces/IJBPermissions.sol +14 -7
- package/src/interfaces/IJBPermitTerminal.sol +4 -0
- package/src/interfaces/IJBPrices.sol +6 -0
- package/src/interfaces/IJBProjects.sol +8 -0
- package/src/interfaces/IJBRulesetApprovalHook.sol +1 -1
- package/src/interfaces/IJBRulesetDataHook.sol +23 -23
- package/src/interfaces/IJBRulesets.sol +54 -33
- package/src/interfaces/IJBSplits.sol +6 -0
- package/src/interfaces/IJBTerminal.sol +36 -0
- package/src/interfaces/IJBTerminalStore.sol +63 -63
- package/src/interfaces/IJBToken.sol +5 -5
- package/src/interfaces/IJBTokens.sol +50 -8
- package/test/TestDurationUnderflow.sol +3 -2
package/src/JBController.sol
CHANGED
|
@@ -150,210 +150,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
//*********************************************************************//
|
|
153
|
-
//
|
|
154
|
-
//*********************************************************************//
|
|
155
|
-
|
|
156
|
-
/// @notice Get an array of a project's rulesets (with metadata) up to a maximum array size, sorted from latest to
|
|
157
|
-
/// earliest.
|
|
158
|
-
/// @param projectId The ID of the project to get the rulesets of.
|
|
159
|
-
/// @param startingId The ID of the ruleset to begin with. This will be the latest ruleset in the result. If the
|
|
160
|
-
/// `startingId` is 0, passed, the project's latest ruleset will be used.
|
|
161
|
-
/// @param size The maximum number of rulesets to return.
|
|
162
|
-
/// @return rulesets The array of rulesets with their metadata.
|
|
163
|
-
function allRulesetsOf(
|
|
164
|
-
uint256 projectId,
|
|
165
|
-
uint256 startingId,
|
|
166
|
-
uint256 size
|
|
167
|
-
)
|
|
168
|
-
external
|
|
169
|
-
view
|
|
170
|
-
override
|
|
171
|
-
returns (JBRulesetWithMetadata[] memory rulesets)
|
|
172
|
-
{
|
|
173
|
-
// Get the rulesets (without metadata).
|
|
174
|
-
JBRuleset[] memory baseRulesets = RULESETS.allOf({projectId: projectId, startingId: startingId, size: size});
|
|
175
|
-
|
|
176
|
-
// Keep a reference to the number of rulesets.
|
|
177
|
-
uint256 numberOfRulesets = baseRulesets.length;
|
|
178
|
-
|
|
179
|
-
// Initialize the array being returned.
|
|
180
|
-
rulesets = new JBRulesetWithMetadata[](numberOfRulesets);
|
|
181
|
-
|
|
182
|
-
// Populate the array with rulesets AND their metadata.
|
|
183
|
-
for (uint256 i; i < numberOfRulesets; i++) {
|
|
184
|
-
// Set the ruleset being iterated on.
|
|
185
|
-
JBRuleset memory baseRuleset = baseRulesets[i];
|
|
186
|
-
|
|
187
|
-
// Set the returned value.
|
|
188
|
-
rulesets[i] = JBRulesetWithMetadata({ruleset: baseRuleset, metadata: baseRuleset.expandMetadata()});
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/// @notice A project's currently active ruleset and its metadata.
|
|
193
|
-
/// @param projectId The ID of the project to get the current ruleset of.
|
|
194
|
-
/// @return ruleset The current ruleset's struct.
|
|
195
|
-
/// @return metadata The current ruleset's metadata.
|
|
196
|
-
function currentRulesetOf(uint256 projectId)
|
|
197
|
-
external
|
|
198
|
-
view
|
|
199
|
-
override
|
|
200
|
-
returns (JBRuleset memory ruleset, JBRulesetMetadata memory metadata)
|
|
201
|
-
{
|
|
202
|
-
ruleset = _currentRulesetOf(projectId);
|
|
203
|
-
metadata = ruleset.expandMetadata();
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/// @notice Get the `JBRuleset` and `JBRulesetMetadata` corresponding to the specified `rulesetId`.
|
|
207
|
-
/// @param projectId The ID of the project the ruleset belongs to.
|
|
208
|
-
/// @return ruleset The ruleset's struct.
|
|
209
|
-
/// @return metadata The ruleset's metadata.
|
|
210
|
-
function getRulesetOf(
|
|
211
|
-
uint256 projectId,
|
|
212
|
-
uint256 rulesetId
|
|
213
|
-
)
|
|
214
|
-
external
|
|
215
|
-
view
|
|
216
|
-
override
|
|
217
|
-
returns (JBRuleset memory ruleset, JBRulesetMetadata memory metadata)
|
|
218
|
-
{
|
|
219
|
-
ruleset = RULESETS.getRulesetOf({projectId: projectId, rulesetId: rulesetId});
|
|
220
|
-
metadata = ruleset.expandMetadata();
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/// @notice Gets the latest ruleset queued for a project, its approval status, and its metadata.
|
|
224
|
-
/// @dev The 'latest queued ruleset' is the ruleset initialized furthest in the future (at the end of the ruleset
|
|
225
|
-
/// queue).
|
|
226
|
-
/// @param projectId The ID of the project to get the latest ruleset of.
|
|
227
|
-
/// @return ruleset The struct for the project's latest queued ruleset.
|
|
228
|
-
/// @return metadata The ruleset's metadata.
|
|
229
|
-
/// @return approvalStatus The ruleset's approval status.
|
|
230
|
-
function latestQueuedRulesetOf(uint256 projectId)
|
|
231
|
-
external
|
|
232
|
-
view
|
|
233
|
-
override
|
|
234
|
-
returns (JBRuleset memory ruleset, JBRulesetMetadata memory metadata, JBApprovalStatus approvalStatus)
|
|
235
|
-
{
|
|
236
|
-
(ruleset, approvalStatus) = RULESETS.latestQueuedOf(projectId);
|
|
237
|
-
metadata = ruleset.expandMetadata();
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/// @notice Check whether the project's terminals can currently be set.
|
|
241
|
-
/// @param projectId The ID of the project to check.
|
|
242
|
-
/// @return A `bool` which is true if the project allows terminals to be set.
|
|
243
|
-
function setTerminalsAllowed(uint256 projectId) external view returns (bool) {
|
|
244
|
-
return _currentRulesetOf(projectId).expandMetadata().allowSetTerminals;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/// @notice Check whether the project's controller can currently be set.
|
|
248
|
-
/// @param projectId The ID of the project to check.
|
|
249
|
-
/// @return A `bool` which is true if the project allows controllers to be set.
|
|
250
|
-
function setControllerAllowed(uint256 projectId) external view returns (bool) {
|
|
251
|
-
return _currentRulesetOf(projectId).expandMetadata().allowSetController;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/// @notice Gets the a project token's total supply, including pending reserved tokens.
|
|
255
|
-
/// @param projectId The ID of the project to get the total token supply of.
|
|
256
|
-
/// @return The total supply of the project's token, including pending reserved tokens.
|
|
257
|
-
function totalTokenSupplyWithReservedTokensOf(uint256 projectId) external view override returns (uint256) {
|
|
258
|
-
// Add the reserved tokens to the total supply.
|
|
259
|
-
return TOKENS.totalSupplyOf(projectId) + pendingReservedTokenBalanceOf[projectId];
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/// @notice A project's next ruleset along with its metadata.
|
|
263
|
-
/// @dev If an upcoming ruleset isn't found, returns an empty ruleset with all properties set to 0.
|
|
264
|
-
/// @param projectId The ID of the project to get the next ruleset of.
|
|
265
|
-
/// @return ruleset The upcoming ruleset's struct.
|
|
266
|
-
/// @return metadata The upcoming ruleset's metadata.
|
|
267
|
-
function upcomingRulesetOf(uint256 projectId)
|
|
268
|
-
external
|
|
269
|
-
view
|
|
270
|
-
override
|
|
271
|
-
returns (JBRuleset memory ruleset, JBRulesetMetadata memory metadata)
|
|
272
|
-
{
|
|
273
|
-
ruleset = _upcomingRulesetOf(projectId);
|
|
274
|
-
metadata = ruleset.expandMetadata();
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
//*********************************************************************//
|
|
278
|
-
// -------------------------- public views --------------------------- //
|
|
279
|
-
//*********************************************************************//
|
|
280
|
-
|
|
281
|
-
/// @notice Indicates whether this contract adheres to the specified interface.
|
|
282
|
-
/// @dev See {IERC165-supportsInterface}.
|
|
283
|
-
/// @param interfaceId The ID of the interface to check for adherence to.
|
|
284
|
-
/// @return A flag indicating if the provided interface ID is supported.
|
|
285
|
-
function supportsInterface(bytes4 interfaceId) public pure override returns (bool) {
|
|
286
|
-
return interfaceId == type(IJBController).interfaceId || interfaceId == type(IJBProjectUriRegistry).interfaceId
|
|
287
|
-
|| interfaceId == type(IJBDirectoryAccessControl).interfaceId
|
|
288
|
-
|| interfaceId == type(IJBMigratable).interfaceId || interfaceId == type(IJBPermissioned).interfaceId
|
|
289
|
-
|| interfaceId == type(IERC165).interfaceId;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
//*********************************************************************//
|
|
293
|
-
// -------------------------- internal views ------------------------- //
|
|
294
|
-
//*********************************************************************//
|
|
295
|
-
|
|
296
|
-
/// @dev `ERC-2771` specifies the context as being a single address (20 bytes).
|
|
297
|
-
function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
|
|
298
|
-
return super._contextSuffixLength();
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/// @notice The project's current ruleset.
|
|
302
|
-
/// @param projectId The ID of the project to check.
|
|
303
|
-
/// @return The project's current ruleset.
|
|
304
|
-
function _currentRulesetOf(uint256 projectId) internal view returns (JBRuleset memory) {
|
|
305
|
-
return RULESETS.currentOf(projectId);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/// @notice Indicates whether the provided address is a terminal for the project.
|
|
309
|
-
/// @param projectId The ID of the project to check.
|
|
310
|
-
/// @param terminal The address to check.
|
|
311
|
-
/// @return A flag indicating if the provided address is a terminal for the project.
|
|
312
|
-
function _isTerminalOf(uint256 projectId, address terminal) internal view returns (bool) {
|
|
313
|
-
return DIRECTORY.isTerminalOf({projectId: projectId, terminal: IJBTerminal(terminal)});
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/// @notice Indicates whether the provided address has mint permission for the project byway of the data hook.
|
|
317
|
-
/// @param projectId The ID of the project to check.
|
|
318
|
-
/// @param ruleset The ruleset to check.
|
|
319
|
-
/// @param addr The address to check.
|
|
320
|
-
/// @return A flag indicating if the provided address has mint permission for the project.
|
|
321
|
-
function _hasDataHookMintPermissionFor(
|
|
322
|
-
uint256 projectId,
|
|
323
|
-
JBRuleset memory ruleset,
|
|
324
|
-
address addr
|
|
325
|
-
)
|
|
326
|
-
internal
|
|
327
|
-
view
|
|
328
|
-
returns (bool)
|
|
329
|
-
{
|
|
330
|
-
address dataHook = ruleset.dataHook();
|
|
331
|
-
|
|
332
|
-
return dataHook != address(0)
|
|
333
|
-
&& IJBRulesetDataHook(dataHook).hasMintPermissionFor({projectId: projectId, ruleset: ruleset, addr: addr});
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/// @notice The calldata. Preferred to use over `msg.data`.
|
|
337
|
-
/// @return calldata The `msg.data` of this call.
|
|
338
|
-
function _msgData() internal view override(ERC2771Context, Context) returns (bytes calldata) {
|
|
339
|
-
return ERC2771Context._msgData();
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/// @notice The message's sender. Preferred to use over `msg.sender`.
|
|
343
|
-
/// @return sender The address which sent this call.
|
|
344
|
-
function _msgSender() internal view override(ERC2771Context, Context) returns (address sender) {
|
|
345
|
-
return ERC2771Context._msgSender();
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/// @notice The project's upcoming ruleset.
|
|
349
|
-
/// @param projectId The ID of the project to check.
|
|
350
|
-
/// @return The project's upcoming ruleset.
|
|
351
|
-
function _upcomingRulesetOf(uint256 projectId) internal view returns (JBRuleset memory) {
|
|
352
|
-
return RULESETS.upcomingOf(projectId);
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
//*********************************************************************//
|
|
356
|
-
// --------------------- external transactions ----------------------- //
|
|
153
|
+
// ---------------------- external transactions ---------------------- //
|
|
357
154
|
//*********************************************************************//
|
|
358
155
|
|
|
359
156
|
/// @notice Add a price feed for a project.
|
|
@@ -386,6 +183,18 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
386
183
|
});
|
|
387
184
|
}
|
|
388
185
|
|
|
186
|
+
/// @notice Called after this controller has been set as the project's controller in the directory.
|
|
187
|
+
/// @dev Can only be called by the directory.
|
|
188
|
+
/// @param from The controller being migrated from.
|
|
189
|
+
/// @param projectId The ID of the project that migrated to this controller.
|
|
190
|
+
function afterReceiveMigrationFrom(IERC165 from, uint256 projectId) external override {
|
|
191
|
+
from; // Suppress unused variable warning.
|
|
192
|
+
projectId; // Suppress unused variable warning.
|
|
193
|
+
|
|
194
|
+
// Make sure the sender is the directory.
|
|
195
|
+
if (_msgSender() != address(DIRECTORY)) revert JBController_OnlyDirectory(_msgSender(), DIRECTORY);
|
|
196
|
+
}
|
|
197
|
+
|
|
389
198
|
/// @notice Prepares this controller to receive a project being migrated from another controller.
|
|
390
199
|
/// @dev This controller should not be the project's controller yet.
|
|
391
200
|
/// @param from The controller being migrated from.
|
|
@@ -412,18 +221,6 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
412
221
|
}
|
|
413
222
|
}
|
|
414
223
|
|
|
415
|
-
/// @notice Called after this controller has been set as the project's controller in the directory.
|
|
416
|
-
/// @dev Can only be called by the directory.
|
|
417
|
-
/// @param from The controller being migrated from.
|
|
418
|
-
/// @param projectId The ID of the project that migrated to this controller.
|
|
419
|
-
function afterReceiveMigrationFrom(IERC165 from, uint256 projectId) external override {
|
|
420
|
-
from; // Suppress unused variable warning.
|
|
421
|
-
projectId; // Suppress unused variable warning.
|
|
422
|
-
|
|
423
|
-
// Make sure the sender is the directory.
|
|
424
|
-
if (_msgSender() != address(DIRECTORY)) revert JBController_OnlyDirectory(_msgSender(), DIRECTORY);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
224
|
/// @notice Burns a project's tokens or credits from the specific holder's balance.
|
|
428
225
|
/// @dev Can only be called by the holder, an address with the holder's permission to `BURN_TOKENS`, or a project's
|
|
429
226
|
/// terminal.
|
|
@@ -895,19 +692,159 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
895
692
|
}
|
|
896
693
|
|
|
897
694
|
//*********************************************************************//
|
|
898
|
-
//
|
|
695
|
+
// ------------------------- external views -------------------------- //
|
|
899
696
|
//*********************************************************************//
|
|
900
697
|
|
|
901
|
-
/// @notice
|
|
902
|
-
///
|
|
903
|
-
/// @param
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
698
|
+
/// @notice Get an array of a project's rulesets (with metadata) up to a maximum array size, sorted from latest to
|
|
699
|
+
/// earliest.
|
|
700
|
+
/// @param projectId The ID of the project to get the rulesets of.
|
|
701
|
+
/// @param startingId The ID of the ruleset to begin with. This will be the latest ruleset in the result. If the
|
|
702
|
+
/// `startingId` is 0, passed, the project's latest ruleset will be used.
|
|
703
|
+
/// @param size The maximum number of rulesets to return.
|
|
704
|
+
/// @return rulesets The array of rulesets with their metadata.
|
|
705
|
+
function allRulesetsOf(
|
|
706
|
+
uint256 projectId,
|
|
707
|
+
uint256 startingId,
|
|
708
|
+
uint256 size
|
|
709
|
+
)
|
|
710
|
+
external
|
|
711
|
+
view
|
|
712
|
+
override
|
|
713
|
+
returns (JBRulesetWithMetadata[] memory rulesets)
|
|
714
|
+
{
|
|
715
|
+
// Get the rulesets (without metadata).
|
|
716
|
+
JBRuleset[] memory baseRulesets = RULESETS.allOf({projectId: projectId, startingId: startingId, size: size});
|
|
907
717
|
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
718
|
+
// Keep a reference to the number of rulesets.
|
|
719
|
+
uint256 numberOfRulesets = baseRulesets.length;
|
|
720
|
+
|
|
721
|
+
// Initialize the array being returned.
|
|
722
|
+
rulesets = new JBRulesetWithMetadata[](numberOfRulesets);
|
|
723
|
+
|
|
724
|
+
// Populate the array with rulesets AND their metadata.
|
|
725
|
+
for (uint256 i; i < numberOfRulesets; i++) {
|
|
726
|
+
// Set the ruleset being iterated on.
|
|
727
|
+
JBRuleset memory baseRuleset = baseRulesets[i];
|
|
728
|
+
|
|
729
|
+
// Set the returned value.
|
|
730
|
+
rulesets[i] = JBRulesetWithMetadata({ruleset: baseRuleset, metadata: baseRuleset.expandMetadata()});
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
/// @notice A project's currently active ruleset and its metadata.
|
|
735
|
+
/// @param projectId The ID of the project to get the current ruleset of.
|
|
736
|
+
/// @return ruleset The current ruleset's struct.
|
|
737
|
+
/// @return metadata The current ruleset's metadata.
|
|
738
|
+
function currentRulesetOf(uint256 projectId)
|
|
739
|
+
external
|
|
740
|
+
view
|
|
741
|
+
override
|
|
742
|
+
returns (JBRuleset memory ruleset, JBRulesetMetadata memory metadata)
|
|
743
|
+
{
|
|
744
|
+
ruleset = _currentRulesetOf(projectId);
|
|
745
|
+
metadata = ruleset.expandMetadata();
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/// @notice Get the `JBRuleset` and `JBRulesetMetadata` corresponding to the specified `rulesetId`.
|
|
749
|
+
/// @param projectId The ID of the project the ruleset belongs to.
|
|
750
|
+
/// @return ruleset The ruleset's struct.
|
|
751
|
+
/// @return metadata The ruleset's metadata.
|
|
752
|
+
function getRulesetOf(
|
|
753
|
+
uint256 projectId,
|
|
754
|
+
uint256 rulesetId
|
|
755
|
+
)
|
|
756
|
+
external
|
|
757
|
+
view
|
|
758
|
+
override
|
|
759
|
+
returns (JBRuleset memory ruleset, JBRulesetMetadata memory metadata)
|
|
760
|
+
{
|
|
761
|
+
ruleset = RULESETS.getRulesetOf({projectId: projectId, rulesetId: rulesetId});
|
|
762
|
+
metadata = ruleset.expandMetadata();
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/// @notice Gets the latest ruleset queued for a project, its approval status, and its metadata.
|
|
766
|
+
/// @dev The 'latest queued ruleset' is the ruleset initialized furthest in the future (at the end of the ruleset
|
|
767
|
+
/// queue).
|
|
768
|
+
/// @param projectId The ID of the project to get the latest ruleset of.
|
|
769
|
+
/// @return ruleset The struct for the project's latest queued ruleset.
|
|
770
|
+
/// @return metadata The ruleset's metadata.
|
|
771
|
+
/// @return approvalStatus The ruleset's approval status.
|
|
772
|
+
function latestQueuedRulesetOf(uint256 projectId)
|
|
773
|
+
external
|
|
774
|
+
view
|
|
775
|
+
override
|
|
776
|
+
returns (JBRuleset memory ruleset, JBRulesetMetadata memory metadata, JBApprovalStatus approvalStatus)
|
|
777
|
+
{
|
|
778
|
+
(ruleset, approvalStatus) = RULESETS.latestQueuedOf(projectId);
|
|
779
|
+
metadata = ruleset.expandMetadata();
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
/// @notice Check whether the project's controller can currently be set.
|
|
783
|
+
/// @param projectId The ID of the project to check.
|
|
784
|
+
/// @return A `bool` which is true if the project allows controllers to be set.
|
|
785
|
+
function setControllerAllowed(uint256 projectId) external view returns (bool) {
|
|
786
|
+
return _currentRulesetOf(projectId).expandMetadata().allowSetController;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/// @notice Check whether the project's terminals can currently be set.
|
|
790
|
+
/// @param projectId The ID of the project to check.
|
|
791
|
+
/// @return A `bool` which is true if the project allows terminals to be set.
|
|
792
|
+
function setTerminalsAllowed(uint256 projectId) external view returns (bool) {
|
|
793
|
+
return _currentRulesetOf(projectId).expandMetadata().allowSetTerminals;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/// @notice Gets the a project token's total supply, including pending reserved tokens.
|
|
797
|
+
/// @param projectId The ID of the project to get the total token supply of.
|
|
798
|
+
/// @return The total supply of the project's token, including pending reserved tokens.
|
|
799
|
+
function totalTokenSupplyWithReservedTokensOf(uint256 projectId) external view override returns (uint256) {
|
|
800
|
+
// Add the reserved tokens to the total supply.
|
|
801
|
+
return TOKENS.totalSupplyOf(projectId) + pendingReservedTokenBalanceOf[projectId];
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/// @notice A project's next ruleset along with its metadata.
|
|
805
|
+
/// @dev If an upcoming ruleset isn't found, returns an empty ruleset with all properties set to 0.
|
|
806
|
+
/// @param projectId The ID of the project to get the next ruleset of.
|
|
807
|
+
/// @return ruleset The upcoming ruleset's struct.
|
|
808
|
+
/// @return metadata The upcoming ruleset's metadata.
|
|
809
|
+
function upcomingRulesetOf(uint256 projectId)
|
|
810
|
+
external
|
|
811
|
+
view
|
|
812
|
+
override
|
|
813
|
+
returns (JBRuleset memory ruleset, JBRulesetMetadata memory metadata)
|
|
814
|
+
{
|
|
815
|
+
ruleset = _upcomingRulesetOf(projectId);
|
|
816
|
+
metadata = ruleset.expandMetadata();
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
//*********************************************************************//
|
|
820
|
+
// -------------------------- public views --------------------------- //
|
|
821
|
+
//*********************************************************************//
|
|
822
|
+
|
|
823
|
+
/// @notice Indicates whether this contract adheres to the specified interface.
|
|
824
|
+
/// @dev See {IERC165-supportsInterface}.
|
|
825
|
+
/// @param interfaceId The ID of the interface to check for adherence to.
|
|
826
|
+
/// @return A flag indicating if the provided interface ID is supported.
|
|
827
|
+
function supportsInterface(bytes4 interfaceId) public pure override returns (bool) {
|
|
828
|
+
return interfaceId == type(IJBController).interfaceId || interfaceId == type(IJBProjectUriRegistry).interfaceId
|
|
829
|
+
|| interfaceId == type(IJBDirectoryAccessControl).interfaceId
|
|
830
|
+
|| interfaceId == type(IJBMigratable).interfaceId || interfaceId == type(IJBPermissioned).interfaceId
|
|
831
|
+
|| interfaceId == type(IERC165).interfaceId;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
//*********************************************************************//
|
|
835
|
+
// ---------------------- internal transactions ---------------------- //
|
|
836
|
+
//*********************************************************************//
|
|
837
|
+
|
|
838
|
+
/// @notice Set up a project's terminals.
|
|
839
|
+
/// @param projectId The ID of the project to set up terminals for.
|
|
840
|
+
/// @param terminalConfigurations The terminals to set up.
|
|
841
|
+
function _configureTerminals(uint256 projectId, JBTerminalConfig[] calldata terminalConfigurations) internal {
|
|
842
|
+
// Initialize an array of terminals to populate.
|
|
843
|
+
IJBTerminal[] memory terminals = new IJBTerminal[](terminalConfigurations.length);
|
|
844
|
+
|
|
845
|
+
for (uint256 i; i < terminalConfigurations.length; i++) {
|
|
846
|
+
// Set the terminal configuration being iterated on.
|
|
847
|
+
JBTerminalConfig memory terminalConfig = terminalConfigurations[i];
|
|
911
848
|
|
|
912
849
|
// Add the accounting contexts for the specified tokens.
|
|
913
850
|
terminalConfig.terminal
|
|
@@ -982,57 +919,6 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
982
919
|
}
|
|
983
920
|
}
|
|
984
921
|
|
|
985
|
-
/// @notice Sends pending reserved tokens to the project's reserved token splits.
|
|
986
|
-
/// @dev If the project has no reserved token splits, or if they don't add up to 100%, leftover tokens are sent to
|
|
987
|
-
/// the project's owner.
|
|
988
|
-
/// @param projectId The ID of the project to send reserved tokens for.
|
|
989
|
-
/// @return tokenCount The amount of reserved tokens minted and sent.
|
|
990
|
-
function _sendReservedTokensToSplitsOf(uint256 projectId) internal returns (uint256 tokenCount) {
|
|
991
|
-
// Get a reference to the number of tokens that need to be minted.
|
|
992
|
-
tokenCount = pendingReservedTokenBalanceOf[projectId];
|
|
993
|
-
|
|
994
|
-
// Revert if there are no pending reserved tokens
|
|
995
|
-
if (tokenCount == 0) revert JBController_NoReservedTokens();
|
|
996
|
-
|
|
997
|
-
// Get the ruleset to read the reserved percent from.
|
|
998
|
-
JBRuleset memory ruleset = _currentRulesetOf(projectId);
|
|
999
|
-
|
|
1000
|
-
// Get a reference to the project's owner.
|
|
1001
|
-
address owner = PROJECTS.ownerOf(projectId);
|
|
1002
|
-
|
|
1003
|
-
// Reset the pending reserved token balance.
|
|
1004
|
-
pendingReservedTokenBalanceOf[projectId] = 0;
|
|
1005
|
-
|
|
1006
|
-
// Mint the tokens to this contract.
|
|
1007
|
-
IJBToken token = TOKENS.mintFor({holder: address(this), projectId: projectId, count: tokenCount});
|
|
1008
|
-
|
|
1009
|
-
// Send reserved tokens to splits and get a reference to the amount left after the splits have all been paid.
|
|
1010
|
-
uint256 leftoverTokenCount = tokenCount == 0
|
|
1011
|
-
? 0
|
|
1012
|
-
: _sendReservedTokensToSplitGroupOf({
|
|
1013
|
-
projectId: projectId,
|
|
1014
|
-
rulesetId: ruleset.id,
|
|
1015
|
-
groupId: JBSplitGroupIds.RESERVED_TOKENS,
|
|
1016
|
-
tokenCount: tokenCount,
|
|
1017
|
-
token: token
|
|
1018
|
-
});
|
|
1019
|
-
|
|
1020
|
-
// Mint any leftover tokens to the project owner.
|
|
1021
|
-
if (leftoverTokenCount > 0) {
|
|
1022
|
-
_sendTokens({projectId: projectId, tokenCount: leftoverTokenCount, recipient: owner, token: token});
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
emit SendReservedTokensToSplits({
|
|
1026
|
-
rulesetId: ruleset.id,
|
|
1027
|
-
rulesetCycleNumber: ruleset.cycleNumber,
|
|
1028
|
-
projectId: projectId,
|
|
1029
|
-
owner: owner,
|
|
1030
|
-
tokenCount: tokenCount,
|
|
1031
|
-
leftoverAmount: leftoverTokenCount,
|
|
1032
|
-
caller: _msgSender()
|
|
1033
|
-
});
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
922
|
/// @notice Send project tokens to a split group.
|
|
1037
923
|
/// @dev This is used to send reserved tokens to the reserved token split group.
|
|
1038
924
|
/// @param projectId The ID of the project the splits belong to.
|
|
@@ -1169,6 +1055,57 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
1169
1055
|
}
|
|
1170
1056
|
}
|
|
1171
1057
|
|
|
1058
|
+
/// @notice Sends pending reserved tokens to the project's reserved token splits.
|
|
1059
|
+
/// @dev If the project has no reserved token splits, or if they don't add up to 100%, leftover tokens are sent to
|
|
1060
|
+
/// the project's owner.
|
|
1061
|
+
/// @param projectId The ID of the project to send reserved tokens for.
|
|
1062
|
+
/// @return tokenCount The amount of reserved tokens minted and sent.
|
|
1063
|
+
function _sendReservedTokensToSplitsOf(uint256 projectId) internal returns (uint256 tokenCount) {
|
|
1064
|
+
// Get a reference to the number of tokens that need to be minted.
|
|
1065
|
+
tokenCount = pendingReservedTokenBalanceOf[projectId];
|
|
1066
|
+
|
|
1067
|
+
// Revert if there are no pending reserved tokens
|
|
1068
|
+
if (tokenCount == 0) revert JBController_NoReservedTokens();
|
|
1069
|
+
|
|
1070
|
+
// Get the ruleset to read the reserved percent from.
|
|
1071
|
+
JBRuleset memory ruleset = _currentRulesetOf(projectId);
|
|
1072
|
+
|
|
1073
|
+
// Get a reference to the project's owner.
|
|
1074
|
+
address owner = PROJECTS.ownerOf(projectId);
|
|
1075
|
+
|
|
1076
|
+
// Reset the pending reserved token balance.
|
|
1077
|
+
pendingReservedTokenBalanceOf[projectId] = 0;
|
|
1078
|
+
|
|
1079
|
+
// Mint the tokens to this contract.
|
|
1080
|
+
IJBToken token = TOKENS.mintFor({holder: address(this), projectId: projectId, count: tokenCount});
|
|
1081
|
+
|
|
1082
|
+
// Send reserved tokens to splits and get a reference to the amount left after the splits have all been paid.
|
|
1083
|
+
uint256 leftoverTokenCount = tokenCount == 0
|
|
1084
|
+
? 0
|
|
1085
|
+
: _sendReservedTokensToSplitGroupOf({
|
|
1086
|
+
projectId: projectId,
|
|
1087
|
+
rulesetId: ruleset.id,
|
|
1088
|
+
groupId: JBSplitGroupIds.RESERVED_TOKENS,
|
|
1089
|
+
tokenCount: tokenCount,
|
|
1090
|
+
token: token
|
|
1091
|
+
});
|
|
1092
|
+
|
|
1093
|
+
// Mint any leftover tokens to the project owner.
|
|
1094
|
+
if (leftoverTokenCount > 0) {
|
|
1095
|
+
_sendTokens({projectId: projectId, tokenCount: leftoverTokenCount, recipient: owner, token: token});
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
emit SendReservedTokensToSplits({
|
|
1099
|
+
rulesetId: ruleset.id,
|
|
1100
|
+
rulesetCycleNumber: ruleset.cycleNumber,
|
|
1101
|
+
projectId: projectId,
|
|
1102
|
+
owner: owner,
|
|
1103
|
+
tokenCount: tokenCount,
|
|
1104
|
+
leftoverAmount: leftoverTokenCount,
|
|
1105
|
+
caller: _msgSender()
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1172
1109
|
/// @notice Send tokens from this contract to a recipient.
|
|
1173
1110
|
/// @param projectId The ID of the project the tokens belong to.
|
|
1174
1111
|
/// @param tokenCount The number of tokens to send.
|
|
@@ -1183,4 +1120,67 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
1183
1120
|
});
|
|
1184
1121
|
}
|
|
1185
1122
|
}
|
|
1123
|
+
|
|
1124
|
+
//*********************************************************************//
|
|
1125
|
+
// -------------------------- internal views ------------------------- //
|
|
1126
|
+
//*********************************************************************//
|
|
1127
|
+
|
|
1128
|
+
/// @dev `ERC-2771` specifies the context as being a single address (20 bytes).
|
|
1129
|
+
function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
|
|
1130
|
+
return super._contextSuffixLength();
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
/// @notice The project's current ruleset.
|
|
1134
|
+
/// @param projectId The ID of the project to check.
|
|
1135
|
+
/// @return The project's current ruleset.
|
|
1136
|
+
function _currentRulesetOf(uint256 projectId) internal view returns (JBRuleset memory) {
|
|
1137
|
+
return RULESETS.currentOf(projectId);
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
/// @notice Indicates whether the provided address has mint permission for the project byway of the data hook.
|
|
1141
|
+
/// @param projectId The ID of the project to check.
|
|
1142
|
+
/// @param ruleset The ruleset to check.
|
|
1143
|
+
/// @param addr The address to check.
|
|
1144
|
+
/// @return A flag indicating if the provided address has mint permission for the project.
|
|
1145
|
+
function _hasDataHookMintPermissionFor(
|
|
1146
|
+
uint256 projectId,
|
|
1147
|
+
JBRuleset memory ruleset,
|
|
1148
|
+
address addr
|
|
1149
|
+
)
|
|
1150
|
+
internal
|
|
1151
|
+
view
|
|
1152
|
+
returns (bool)
|
|
1153
|
+
{
|
|
1154
|
+
address dataHook = ruleset.dataHook();
|
|
1155
|
+
|
|
1156
|
+
return dataHook != address(0)
|
|
1157
|
+
&& IJBRulesetDataHook(dataHook).hasMintPermissionFor({projectId: projectId, ruleset: ruleset, addr: addr});
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
/// @notice Indicates whether the provided address is a terminal for the project.
|
|
1161
|
+
/// @param projectId The ID of the project to check.
|
|
1162
|
+
/// @param terminal The address to check.
|
|
1163
|
+
/// @return A flag indicating if the provided address is a terminal for the project.
|
|
1164
|
+
function _isTerminalOf(uint256 projectId, address terminal) internal view returns (bool) {
|
|
1165
|
+
return DIRECTORY.isTerminalOf({projectId: projectId, terminal: IJBTerminal(terminal)});
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
/// @notice The calldata. Preferred to use over `msg.data`.
|
|
1169
|
+
/// @return calldata The `msg.data` of this call.
|
|
1170
|
+
function _msgData() internal view override(ERC2771Context, Context) returns (bytes calldata) {
|
|
1171
|
+
return ERC2771Context._msgData();
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
/// @notice The message's sender. Preferred to use over `msg.sender`.
|
|
1175
|
+
/// @return sender The address which sent this call.
|
|
1176
|
+
function _msgSender() internal view override(ERC2771Context, Context) returns (address sender) {
|
|
1177
|
+
return ERC2771Context._msgSender();
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
/// @notice The project's upcoming ruleset.
|
|
1181
|
+
/// @param projectId The ID of the project to check.
|
|
1182
|
+
/// @return The project's upcoming ruleset.
|
|
1183
|
+
function _upcomingRulesetOf(uint256 projectId) internal view returns (JBRuleset memory) {
|
|
1184
|
+
return RULESETS.upcomingOf(projectId);
|
|
1185
|
+
}
|
|
1186
1186
|
}
|
package/src/JBDeadline.sol
CHANGED
|
@@ -3,9 +3,9 @@ pragma solidity 0.8.26;
|
|
|
3
3
|
|
|
4
4
|
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
5
5
|
|
|
6
|
-
import {JBRuleset} from "./structs/JBRuleset.sol";
|
|
7
6
|
import {JBApprovalStatus} from "./enums/JBApprovalStatus.sol";
|
|
8
7
|
import {IJBRulesetApprovalHook} from "./interfaces/IJBRulesetApprovalHook.sol";
|
|
8
|
+
import {JBRuleset} from "./structs/JBRuleset.sol";
|
|
9
9
|
|
|
10
10
|
/// @notice `JBDeadline` is a ruleset approval hook which rejects rulesets if they are not queued at least `duration`
|
|
11
11
|
/// seconds before the current ruleset ends. In other words, rulesets must be queued before the deadline to take effect.
|