@bananapus/core-v6 0.0.38 → 0.0.39
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/foundry.toml +1 -1
- package/package.json +1 -1
- package/src/JBChainlinkV3PriceFeed.sol +4 -1
- package/src/JBChainlinkV3SequencerPriceFeed.sol +4 -2
- package/src/JBController.sol +52 -43
- package/src/JBDeadline.sol +4 -4
- package/src/JBDirectory.sol +34 -32
- package/src/JBERC20.sol +5 -4
- package/src/JBFeelessAddresses.sol +6 -3
- package/src/JBFundAccessLimits.sol +25 -21
- package/src/JBMultiTerminal.sol +53 -50
- package/src/JBPermissions.sol +34 -37
- package/src/JBPrices.sol +23 -18
- package/src/JBProjects.sol +6 -3
- package/src/JBRulesets.sol +44 -41
- package/src/JBSplits.sol +18 -16
- package/src/JBTerminalStore.sol +26 -19
- package/src/JBTokens.sol +36 -26
- package/src/abstract/JBControlled.sol +3 -1
- package/src/abstract/JBPermissioned.sol +3 -1
- package/src/enums/JBApprovalStatus.sol +7 -1
- package/src/interfaces/IJBController.sol +3 -2
- package/src/interfaces/IJBDirectory.sol +3 -1
- package/src/interfaces/IJBMultiTerminal.sol +3 -2
- package/src/interfaces/IJBPermissions.sol +2 -1
- package/src/interfaces/IJBPrices.sol +3 -1
- package/src/interfaces/IJBRulesets.sol +2 -1
- package/src/interfaces/IJBSplits.sol +2 -1
- package/src/interfaces/IJBTerminal.sol +3 -1
- package/src/interfaces/IJBTerminalStore.sol +3 -1
- package/src/interfaces/IJBTokens.sol +2 -1
- package/src/libraries/JBCashOuts.sol +6 -1
- package/src/libraries/JBConstants.sol +12 -3
- package/src/libraries/JBCurrencyIds.sol +2 -0
- package/src/libraries/JBFees.sol +5 -1
- package/src/libraries/JBFixedPointNumber.sol +2 -0
- package/src/libraries/JBPayoutSplitGroupLib.sol +5 -2
- package/src/libraries/JBRulesetMetadataResolver.sol +4 -0
- package/src/libraries/JBSplitGroupIds.sol +2 -1
- package/src/libraries/JBSurplus.sol +3 -1
- package/src/periphery/JBMatchingPriceFeed.sol +2 -0
- package/src/structs/JBAccountingContext.sol +7 -4
- package/src/structs/JBFundAccessLimitGroup.sol +10 -17
- package/src/structs/JBRuleset.sol +18 -26
- package/src/structs/JBRulesetConfig.sol +13 -25
- package/src/structs/JBRulesetMetadata.sol +25 -32
package/foundry.toml
CHANGED
|
@@ -17,7 +17,7 @@ fail_on_revert = false
|
|
|
17
17
|
ethereum = "${RPC_ETHEREUM_MAINNET}"
|
|
18
18
|
|
|
19
19
|
[lint]
|
|
20
|
-
exclude_lints = ["
|
|
20
|
+
exclude_lints = ["mixed-case-variable", "pascal-case-struct"]
|
|
21
21
|
[fmt]
|
|
22
22
|
number_underscore = "thousands"
|
|
23
23
|
multiline_func_header = "all"
|
package/package.json
CHANGED
|
@@ -6,7 +6,9 @@ import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interf
|
|
|
6
6
|
import {IJBPriceFeed} from "./interfaces/IJBPriceFeed.sol";
|
|
7
7
|
import {JBFixedPointNumber} from "./libraries/JBFixedPointNumber.sol";
|
|
8
8
|
|
|
9
|
-
/// @notice
|
|
9
|
+
/// @notice A price feed adapter that reads from a Chainlink V3 aggregator. Reverts if the price is stale (older than
|
|
10
|
+
/// `THRESHOLD` seconds), negative, or from an incomplete round — protecting against serving outdated oracle data.
|
|
11
|
+
/// Used by `JBPrices` to convert between currencies (e.g. ETH/USD).
|
|
10
12
|
contract JBChainlinkV3PriceFeed is IJBPriceFeed {
|
|
11
13
|
// A library that provides utility for fixed point numbers.
|
|
12
14
|
using JBFixedPointNumber for uint256;
|
|
@@ -60,6 +62,7 @@ contract JBChainlinkV3PriceFeed is IJBPriceFeed {
|
|
|
60
62
|
if (answeredInRound < roundId) revert JBChainlinkV3PriceFeed_IncompleteRound();
|
|
61
63
|
|
|
62
64
|
// Make sure the price's update threshold is met.
|
|
65
|
+
// forge-lint: disable-next-line(block-timestamp)
|
|
63
66
|
if (block.timestamp > THRESHOLD + updatedAt) {
|
|
64
67
|
revert JBChainlinkV3PriceFeed_StalePrice(block.timestamp, THRESHOLD, updatedAt);
|
|
65
68
|
}
|
|
@@ -6,8 +6,9 @@ import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interf
|
|
|
6
6
|
|
|
7
7
|
import {JBChainlinkV3PriceFeed} from "./JBChainlinkV3PriceFeed.sol";
|
|
8
8
|
|
|
9
|
-
/// @notice
|
|
10
|
-
///
|
|
9
|
+
/// @notice Extends `JBChainlinkV3PriceFeed` with L2 sequencer uptime checks (for Optimism, Arbitrum, etc.). Reverts if
|
|
10
|
+
/// the sequencer is down or has not been back online for at least `GRACE_PERIOD_TIME` seconds — preventing stale
|
|
11
|
+
/// prices from being used immediately after an outage.
|
|
11
12
|
contract JBChainlinkV3SequencerPriceFeed is JBChainlinkV3PriceFeed {
|
|
12
13
|
//*********************************************************************//
|
|
13
14
|
// --------------------------- custom errors ------------------------- //
|
|
@@ -64,6 +65,7 @@ contract JBChainlinkV3SequencerPriceFeed is JBChainlinkV3PriceFeed {
|
|
|
64
65
|
if (startedAt == 0) revert JBChainlinkV3SequencerPriceFeed_InvalidRound();
|
|
65
66
|
|
|
66
67
|
// Revert if sequencer has too recently restarted or is currently down.
|
|
68
|
+
// forge-lint: disable-next-line(block-timestamp)
|
|
67
69
|
if (block.timestamp <= GRACE_PERIOD_TIME + startedAt || answer != 0) {
|
|
68
70
|
revert JBChainlinkV3SequencerPriceFeed_SequencerDownOrRestarting(
|
|
69
71
|
block.timestamp, GRACE_PERIOD_TIME, startedAt
|
package/src/JBController.sol
CHANGED
|
@@ -41,8 +41,13 @@ import {JBSplitGroup} from "./structs/JBSplitGroup.sol";
|
|
|
41
41
|
import {JBSplitHookContext} from "./structs/JBSplitHookContext.sol";
|
|
42
42
|
import {JBTerminalConfig} from "./structs/JBTerminalConfig.sol";
|
|
43
43
|
|
|
44
|
-
/// @notice
|
|
45
|
-
///
|
|
44
|
+
/// @notice The orchestrator for every Juicebox project's lifecycle. Use the controller to launch a project, queue new
|
|
45
|
+
/// rulesets (funding cycles), mint or burn tokens, deploy an ERC-20, distribute reserved tokens, and manage
|
|
46
|
+
/// permissions. The controller coordinates between the terminal (money), rulesets (rules), tokens (issuance), and
|
|
47
|
+
/// splits (distribution).
|
|
48
|
+
/// @dev Supports ERC-2771 meta-transactions. Implements `IJBMigratable` for controller-to-controller migration.
|
|
49
|
+
/// An omnichain deployer address is trusted to launch and queue rulesets on behalf of any project for cross-chain
|
|
50
|
+
/// coordination.
|
|
46
51
|
contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigratable {
|
|
47
52
|
// A library that parses packed ruleset metadata into a friendlier format.
|
|
48
53
|
using JBRulesetMetadataResolver for JBRuleset;
|
|
@@ -166,8 +171,9 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
166
171
|
// ---------------------- external transactions ---------------------- //
|
|
167
172
|
//*********************************************************************//
|
|
168
173
|
|
|
169
|
-
/// @notice
|
|
170
|
-
/// @dev Can only be called by the project's owner or an
|
|
174
|
+
/// @notice Registers a price feed so the project can use a new currency for payout limits or surplus allowances.
|
|
175
|
+
/// @dev Can only be called by the project's owner or an operator with `ADD_PRICE_FEED` permission. The current
|
|
176
|
+
/// ruleset must have `allowAddPriceFeed` enabled.
|
|
171
177
|
/// @param projectId The ID of the project to add the feed for.
|
|
172
178
|
/// @param pricingCurrency The currency the feed's output price is in terms of.
|
|
173
179
|
/// @param unitCurrency The currency being priced by the feed.
|
|
@@ -234,9 +240,9 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
234
240
|
}
|
|
235
241
|
}
|
|
236
242
|
|
|
237
|
-
/// @notice Burns a
|
|
238
|
-
///
|
|
239
|
-
/// terminal.
|
|
243
|
+
/// @notice Burns a holder's project tokens (or credits), permanently removing them from supply. Used by terminals
|
|
244
|
+
/// during cash outs, or directly by holders who want to burn voluntarily.
|
|
245
|
+
/// @dev Can only be called by the holder, an operator with `BURN_TOKENS` permission, or a project terminal.
|
|
240
246
|
/// @param holder The address whose tokens are being burned.
|
|
241
247
|
/// @param projectId The ID of the project whose tokens are being burned.
|
|
242
248
|
/// @param tokenCount The number of tokens to burn.
|
|
@@ -269,8 +275,9 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
269
275
|
TOKENS.burnFrom({holder: holder, projectId: projectId, count: tokenCount});
|
|
270
276
|
}
|
|
271
277
|
|
|
272
|
-
/// @notice
|
|
273
|
-
///
|
|
278
|
+
/// @notice Converts internal credits into the project's ERC-20 token, transferring them to the beneficiary's
|
|
279
|
+
/// wallet. Credits and ERC-20 tokens are interchangeable — this just makes them transferable/tradeable.
|
|
280
|
+
/// @dev Can only be called by the credit holder or an operator with `CLAIM_TOKENS` permission.
|
|
274
281
|
/// @param holder The address to redeem credits from.
|
|
275
282
|
/// @param projectId The ID of the project whose tokens are being claimed.
|
|
276
283
|
/// @param tokenCount The number of tokens to claim.
|
|
@@ -290,9 +297,10 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
290
297
|
TOKENS.claimTokensFor({holder: holder, projectId: projectId, count: tokenCount, beneficiary: beneficiary});
|
|
291
298
|
}
|
|
292
299
|
|
|
293
|
-
/// @notice Deploys
|
|
294
|
-
///
|
|
295
|
-
/// @dev Can only be called by the project's owner or an
|
|
300
|
+
/// @notice Deploys a new ERC-20 token for a project. Once deployed, holders can claim their credits as this token.
|
|
301
|
+
/// Includes ERC20Votes (governance) and ERC20Permit (gasless approvals).
|
|
302
|
+
/// @dev Can only be called by the project's owner or an operator with `DEPLOY_ERC20` permission.
|
|
303
|
+
/// @dev Each project can only have one ERC-20 deployed — calling this again after deployment will revert.
|
|
296
304
|
/// @param projectId The ID of the project to deploy the ERC-20 for.
|
|
297
305
|
/// @param name The ERC-20's name.
|
|
298
306
|
/// @param symbol The ERC-20's symbol.
|
|
@@ -368,10 +376,11 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
368
376
|
}
|
|
369
377
|
}
|
|
370
378
|
|
|
371
|
-
/// @notice Creates a project
|
|
372
|
-
///
|
|
373
|
-
///
|
|
374
|
-
/// @dev Anyone can
|
|
379
|
+
/// @notice Creates a new Juicebox project in one transaction — mints the project NFT, queues initial rulesets,
|
|
380
|
+
/// and
|
|
381
|
+
/// configures terminals. This is the primary entry point for launching a project.
|
|
382
|
+
/// @dev Anyone can call this on behalf of any owner. Each sub-operation (mint, queue, configure) can also be done
|
|
383
|
+
/// individually if needed.
|
|
375
384
|
/// @param owner The project's owner. The project ERC-721 will be minted to this address.
|
|
376
385
|
/// @param projectUri The project's metadata URI. This is typically an IPFS hash, optionally with the `ipfs://`
|
|
377
386
|
/// prefix. This can be updated by the project's owner.
|
|
@@ -414,10 +423,10 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
414
423
|
});
|
|
415
424
|
}
|
|
416
425
|
|
|
417
|
-
/// @notice
|
|
418
|
-
///
|
|
419
|
-
/// @dev
|
|
420
|
-
/// @dev
|
|
426
|
+
/// @notice Queues the first rulesets for an existing project and configures its terminals. For projects that
|
|
427
|
+
/// already have active rulesets, use `queueRulesetsOf(...)` instead.
|
|
428
|
+
/// @dev Can only be called by the project's owner or an operator with `LAUNCH_RULESETS` permission.
|
|
429
|
+
/// @dev Each sub-operation can also be done individually if needed.
|
|
421
430
|
/// @param projectId The ID of the project to launch rulesets for.
|
|
422
431
|
/// @param projectUri The project's metadata URI. Pass an empty string to leave it unchanged.
|
|
423
432
|
/// @param rulesetConfigurations The rulesets to queue.
|
|
@@ -508,12 +517,10 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
508
517
|
if (pendingReservedTokenBalance != 0) revert JBController_PendingReservedTokens(pendingReservedTokenBalance);
|
|
509
518
|
}
|
|
510
519
|
|
|
511
|
-
/// @notice
|
|
512
|
-
///
|
|
513
|
-
/// @dev Can
|
|
514
|
-
/// the
|
|
515
|
-
/// @dev If the ruleset's metadata has `allowOwnerMinting` set to `false`, this function can only be called by the
|
|
516
|
-
/// project's terminals or data hook.
|
|
520
|
+
/// @notice Mints new project tokens to a beneficiary. Optionally reserves a portion according to the ruleset's
|
|
521
|
+
/// reserved percent (which accumulates until `sendReservedTokensToSplitsOf` is called).
|
|
522
|
+
/// @dev Can be called by the project owner, an operator with `MINT_TOKENS` permission, a project terminal, or the
|
|
523
|
+
/// data hook. If `allowOwnerMinting` is false in the current ruleset, only terminals and the data hook can mint.
|
|
517
524
|
/// @param projectId The ID of the project whose tokens are being minted.
|
|
518
525
|
/// @param tokenCount The number of tokens to mint, including any reserved tokens.
|
|
519
526
|
/// @param beneficiary The address which will receive the (non-reserved) tokens.
|
|
@@ -594,9 +601,9 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
594
601
|
}
|
|
595
602
|
}
|
|
596
603
|
|
|
597
|
-
/// @notice
|
|
598
|
-
/// previous ruleset
|
|
599
|
-
/// @dev Can only be called by the project's owner or an
|
|
604
|
+
/// @notice Queues new rulesets to take effect after the current one ends. Each queued ruleset must be approved by
|
|
605
|
+
/// the previous ruleset's approval hook (if one is set) before it can take effect.
|
|
606
|
+
/// @dev Can only be called by the project's owner or an operator with `QUEUE_RULESETS` permission.
|
|
600
607
|
/// @param projectId The ID of the project to queue rulesets for.
|
|
601
608
|
/// @param rulesetConfigurations The rulesets to queue.
|
|
602
609
|
/// @param memo A memo to pass along to the emitted event.
|
|
@@ -628,17 +635,18 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
628
635
|
emit QueueRulesets({rulesetId: rulesetId, projectId: projectId, memo: memo, caller: _msgSender()});
|
|
629
636
|
}
|
|
630
637
|
|
|
631
|
-
/// @notice
|
|
632
|
-
///
|
|
633
|
-
/// the project
|
|
638
|
+
/// @notice Mints and distributes all pending reserved tokens to the project's reserved token split recipients.
|
|
639
|
+
/// Anyone can call this — it's permissionless.
|
|
640
|
+
/// @dev If splits don't add up to 100%, the remainder goes to the project owner.
|
|
634
641
|
/// @param projectId The ID of the project to send reserved tokens for.
|
|
635
642
|
/// @return The amount of reserved tokens minted and sent.
|
|
636
643
|
function sendReservedTokensToSplitsOf(uint256 projectId) external override returns (uint256) {
|
|
637
644
|
return _sendReservedTokensToSplitsOf(projectId);
|
|
638
645
|
}
|
|
639
646
|
|
|
640
|
-
/// @notice
|
|
641
|
-
///
|
|
647
|
+
/// @notice Configures how a project distributes payouts and reserved tokens. Locked splits from the current
|
|
648
|
+
/// configuration must be preserved in the new split groups.
|
|
649
|
+
/// @dev Can only be called by the project's owner or an operator with `SET_SPLIT_GROUPS` permission.
|
|
642
650
|
/// @param projectId The ID of the project to set the split groups of.
|
|
643
651
|
/// @param rulesetId The ID of the ruleset the split groups should be active in. Use a `rulesetId` of 0 to set the
|
|
644
652
|
/// default split groups, which are used when a ruleset has no splits set. If there are no default splits and no
|
|
@@ -716,8 +724,10 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
716
724
|
emit SetUri({projectId: projectId, uri: uri, caller: _msgSender()});
|
|
717
725
|
}
|
|
718
726
|
|
|
719
|
-
/// @notice
|
|
720
|
-
///
|
|
727
|
+
/// @notice Transfers internal credits (unclaimed tokens) from one address to another. Credits function like tokens
|
|
728
|
+
/// but live inside the protocol rather than as an ERC-20.
|
|
729
|
+
/// @dev Can only be called by the credit holder or an operator with `TRANSFER_CREDITS` permission. The current
|
|
730
|
+
/// ruleset must not have credit transfers paused.
|
|
721
731
|
/// @param holder The address to transfer credits from.
|
|
722
732
|
/// @param projectId The ID of the project whose credits are being transferred.
|
|
723
733
|
/// @param recipient The address to transfer credits to.
|
|
@@ -747,8 +757,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
747
757
|
// ------------------------- external views -------------------------- //
|
|
748
758
|
//*********************************************************************//
|
|
749
759
|
|
|
750
|
-
/// @notice
|
|
751
|
-
/// earliest.
|
|
760
|
+
/// @notice Returns a paginated history of a project's rulesets (with decoded metadata), sorted newest-first.
|
|
752
761
|
/// @param projectId The ID of the project to get the rulesets of.
|
|
753
762
|
/// @param startingId The ID of the ruleset to begin with. This will be the latest ruleset in the result. If the
|
|
754
763
|
/// `startingId` is 0, passed, the project's latest ruleset will be used.
|
|
@@ -786,7 +795,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
786
795
|
}
|
|
787
796
|
}
|
|
788
797
|
|
|
789
|
-
/// @notice
|
|
798
|
+
/// @notice Returns the ruleset currently governing a project, along with its decoded metadata.
|
|
790
799
|
/// @param projectId The ID of the project to get the current ruleset of.
|
|
791
800
|
/// @return ruleset The current ruleset's struct.
|
|
792
801
|
/// @return metadata The current ruleset's metadata.
|
|
@@ -862,21 +871,21 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
862
871
|
});
|
|
863
872
|
}
|
|
864
873
|
|
|
865
|
-
/// @notice
|
|
874
|
+
/// @notice Whether the project's current ruleset allows migrating to a different controller.
|
|
866
875
|
/// @param projectId The ID of the project to check.
|
|
867
876
|
/// @return A `bool` which is true if the project allows controllers to be set.
|
|
868
877
|
function setControllerAllowed(uint256 projectId) external view returns (bool) {
|
|
869
878
|
return _currentRulesetOf(projectId).expandMetadata().allowSetController;
|
|
870
879
|
}
|
|
871
880
|
|
|
872
|
-
/// @notice
|
|
881
|
+
/// @notice Whether the project's current ruleset allows changing its terminals.
|
|
873
882
|
/// @param projectId The ID of the project to check.
|
|
874
883
|
/// @return A `bool` which is true if the project allows terminals to be set.
|
|
875
884
|
function setTerminalsAllowed(uint256 projectId) external view returns (bool) {
|
|
876
885
|
return _currentRulesetOf(projectId).expandMetadata().allowSetTerminals;
|
|
877
886
|
}
|
|
878
887
|
|
|
879
|
-
/// @notice
|
|
888
|
+
/// @notice Returns the project's total token supply including tokens that have been reserved but not yet minted.
|
|
880
889
|
/// @param projectId The ID of the project to get the total token supply of.
|
|
881
890
|
/// @return The total supply of the project's token, including pending reserved tokens.
|
|
882
891
|
function totalTokenSupplyWithReservedTokensOf(uint256 projectId) external view override returns (uint256) {
|
|
@@ -884,7 +893,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
884
893
|
return TOKENS.totalSupplyOf(projectId) + pendingReservedTokenBalanceOf[projectId];
|
|
885
894
|
}
|
|
886
895
|
|
|
887
|
-
/// @notice
|
|
896
|
+
/// @notice Returns the ruleset that will take effect after the current one ends, along with its decoded metadata.
|
|
888
897
|
/// @dev If an upcoming ruleset isn't found, returns an empty ruleset with all properties set to 0.
|
|
889
898
|
/// @param projectId The ID of the project to get the next ruleset of.
|
|
890
899
|
/// @return ruleset The upcoming ruleset's struct.
|
package/src/JBDeadline.sol
CHANGED
|
@@ -7,10 +7,9 @@ import {JBApprovalStatus} from "./enums/JBApprovalStatus.sol";
|
|
|
7
7
|
import {IJBRulesetApprovalHook} from "./interfaces/IJBRulesetApprovalHook.sol";
|
|
8
8
|
import {JBRuleset} from "./structs/JBRuleset.sol";
|
|
9
9
|
|
|
10
|
-
/// @notice
|
|
11
|
-
/// seconds before the current ruleset ends
|
|
12
|
-
///
|
|
13
|
-
/// only if they are approved by the previous ruleset's approval hook.
|
|
10
|
+
/// @notice A ruleset approval hook that enforces a queuing deadline. If a new ruleset is not queued at least `DURATION`
|
|
11
|
+
/// seconds before the current ruleset ends, it is rejected and the existing rules continue. This gives token holders
|
|
12
|
+
/// a guaranteed notice period before any project configuration changes take effect.
|
|
14
13
|
/// @dev If `DURATION` is set longer than the ruleset's cycle duration, no queued ruleset can ever satisfy the deadline
|
|
15
14
|
/// and the current ruleset will effectively be locked in perpetuity. Choose a `DURATION` shorter than the shortest
|
|
16
15
|
/// cycle it will govern.
|
|
@@ -60,6 +59,7 @@ contract JBDeadline is IJBRulesetApprovalHook {
|
|
|
60
59
|
// If we've already passed the deadline, the ruleset is `Approved`.
|
|
61
60
|
return (ruleset.start - ruleset.id < DURATION)
|
|
62
61
|
? JBApprovalStatus.Failed
|
|
62
|
+
// forge-lint: disable-next-line(block-timestamp)
|
|
63
63
|
: (block.timestamp + DURATION < ruleset.start)
|
|
64
64
|
? JBApprovalStatus.ApprovalExpected
|
|
65
65
|
: JBApprovalStatus.Approved;
|
package/src/JBDirectory.sol
CHANGED
|
@@ -13,9 +13,11 @@ import {IJBPermissions} from "./interfaces/IJBPermissions.sol";
|
|
|
13
13
|
import {IJBProjects} from "./interfaces/IJBProjects.sol";
|
|
14
14
|
import {IJBTerminal} from "./interfaces/IJBTerminal.sol";
|
|
15
15
|
|
|
16
|
-
/// @notice
|
|
17
|
-
///
|
|
18
|
-
///
|
|
16
|
+
/// @notice The routing table for the protocol. Every project registers which terminals accept its payments and which
|
|
17
|
+
/// controller manages its rulesets and tokens. Frontends and other contracts use the directory to discover where to
|
|
18
|
+
/// send funds for a given project and token.
|
|
19
|
+
/// @dev Also manages controller migration — when a project upgrades its controller, the directory orchestrates the
|
|
20
|
+
/// handoff including `beforeReceiveMigrationFrom`, `migrate`, and `afterReceiveMigrationFrom` lifecycle hooks.
|
|
19
21
|
contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
20
22
|
//*********************************************************************//
|
|
21
23
|
// --------------------------- custom errors ------------------------- //
|
|
@@ -83,12 +85,14 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
83
85
|
// ---------------------- external transactions ---------------------- //
|
|
84
86
|
//*********************************************************************//
|
|
85
87
|
|
|
86
|
-
/// @notice
|
|
88
|
+
/// @notice Assign a new controller to a project. The controller dictates how the project's terminals interact with
|
|
89
|
+
/// its tokens and rulesets. If the project already has a controller, this triggers a full migration lifecycle
|
|
90
|
+
/// (`beforeReceiveMigrationFrom` → `migrate` → state update → `afterReceiveMigrationFrom`).
|
|
87
91
|
/// @dev Can only be called if:
|
|
88
|
-
/// - The ruleset's metadata has `allowSetController` enabled, and the
|
|
89
|
-
///
|
|
90
|
-
/// - OR the
|
|
91
|
-
/// - OR
|
|
92
|
+
/// - The ruleset's metadata has `allowSetController` enabled, and the caller is the project's owner or has
|
|
93
|
+
/// `SET_CONTROLLER` permission.
|
|
94
|
+
/// - OR the caller is the project's current controller.
|
|
95
|
+
/// - OR the caller `isAllowedToSetFirstController` and the project has no controller yet.
|
|
92
96
|
/// @param projectId The ID of the project whose controller is being set.
|
|
93
97
|
/// @param controller The address of the controller to set.
|
|
94
98
|
function setControllerOf(uint256 projectId, IERC165 controller) external override {
|
|
@@ -149,15 +153,13 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
149
153
|
}
|
|
150
154
|
}
|
|
151
155
|
|
|
152
|
-
/// @notice
|
|
153
|
-
/// controller
|
|
154
|
-
/// @dev Only this contract's owner can call this function.
|
|
155
|
-
///
|
|
156
|
-
///
|
|
157
|
-
/// @
|
|
158
|
-
/// @param
|
|
159
|
-
/// @param flag Whether the address is allowed to set first controllers for projects. Use `true` to allow and
|
|
160
|
-
/// `false` to not allow.
|
|
156
|
+
/// @notice Allow or disallow an address to set the first controller for new projects. Typically used to whitelist
|
|
157
|
+
/// deployer contracts (like `JBController`) that set a controller during `launchProjectFor`.
|
|
158
|
+
/// @dev Only this contract's owner can call this function. These addresses are vetted controllers and project
|
|
159
|
+
/// launchers. A project owner can always set their own controller — this list only governs *first* controller
|
|
160
|
+
/// assignment by third parties.
|
|
161
|
+
/// @param addr The address to allow or disallow.
|
|
162
|
+
/// @param flag Whether the address is allowed to set first controllers. `true` to allow, `false` to revoke.
|
|
161
163
|
function setIsAllowedToSetFirstController(address addr, bool flag) external override onlyOwner {
|
|
162
164
|
// Set the flag in the allowlist.
|
|
163
165
|
isAllowedToSetFirstController[addr] = flag;
|
|
@@ -165,11 +167,11 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
165
167
|
emit SetIsAllowedToSetFirstController({addr: addr, isAllowed: flag, caller: msg.sender});
|
|
166
168
|
}
|
|
167
169
|
|
|
168
|
-
/// @notice
|
|
169
|
-
///
|
|
170
|
-
/// @dev
|
|
171
|
-
///
|
|
172
|
-
/// `
|
|
170
|
+
/// @notice Designate which terminal should receive payments by default when someone pays a project in a specific
|
|
171
|
+
/// token. Useful when a project has multiple terminals that accept the same token.
|
|
172
|
+
/// @dev Can only be called by the project's owner or an address with `SET_PRIMARY_TERMINAL` permission. The
|
|
173
|
+
/// terminal must accept the token for this project. If the terminal isn't already in the project's terminal list,
|
|
174
|
+
/// it will be added automatically (requires `ADD_TERMINALS` permission).
|
|
173
175
|
/// @param projectId The ID of the project whose primary terminal is being set.
|
|
174
176
|
/// @param token The token to set the primary terminal for.
|
|
175
177
|
/// @param terminal The terminal being set as the primary terminal.
|
|
@@ -203,10 +205,10 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
203
205
|
emit SetPrimaryTerminal({projectId: projectId, token: token, terminal: terminal, caller: msg.sender});
|
|
204
206
|
}
|
|
205
207
|
|
|
206
|
-
/// @notice
|
|
207
|
-
///
|
|
208
|
-
/// the project's
|
|
209
|
-
///
|
|
208
|
+
/// @notice Replace a project's entire terminal list. Terminals are the contracts that accept payments and process
|
|
209
|
+
/// cash outs for a project. This overwrites the existing list.
|
|
210
|
+
/// @dev Can only be called by the project's owner, an address with `SET_TERMINALS` permission, or the project's
|
|
211
|
+
/// controller. Unless the caller is the controller, the ruleset must have `allowSetTerminals` enabled.
|
|
210
212
|
/// @param projectId The ID of the project whose terminals are being set.
|
|
211
213
|
/// @param terminals An array of terminal addresses to set for the project.
|
|
212
214
|
function setTerminalsOf(uint256 projectId, IJBTerminal[] calldata terminals) external override {
|
|
@@ -254,10 +256,9 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
254
256
|
// ------------------------- external views -------------------------- //
|
|
255
257
|
//*********************************************************************//
|
|
256
258
|
|
|
257
|
-
/// @notice
|
|
258
|
-
///
|
|
259
|
-
///
|
|
260
|
-
/// @dev Returns the zero address if no terminal accepts the token.
|
|
259
|
+
/// @notice Look up the terminal where payments in a given token should be sent for a project. Returns the
|
|
260
|
+
/// explicitly-set primary terminal, or falls back to the first terminal in the project's list that accepts the
|
|
261
|
+
/// token. Returns the zero address if no terminal accepts the token.
|
|
261
262
|
/// @param projectId The ID of the project to get the primary terminal of.
|
|
262
263
|
/// @param token The token that the terminal accepts.
|
|
263
264
|
/// @return The primary terminal's address.
|
|
@@ -298,7 +299,8 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
298
299
|
return IJBTerminal(address(0));
|
|
299
300
|
}
|
|
300
301
|
|
|
301
|
-
/// @notice
|
|
302
|
+
/// @notice Get all terminals registered for a project. Terminals are the contracts that hold a project's funds and
|
|
303
|
+
/// process payments and cash outs on its behalf.
|
|
302
304
|
/// @param projectId The ID of the project to get the terminals of.
|
|
303
305
|
/// @return An array of the project's terminal addresses.
|
|
304
306
|
function terminalsOf(uint256 projectId) external view override returns (IJBTerminal[] memory) {
|
|
@@ -309,7 +311,7 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
309
311
|
// -------------------------- public views --------------------------- //
|
|
310
312
|
//*********************************************************************//
|
|
311
313
|
|
|
312
|
-
/// @notice Check
|
|
314
|
+
/// @notice Check whether a specific terminal is in a project's registered terminal list.
|
|
313
315
|
/// @param projectId The ID of the project to check.
|
|
314
316
|
/// @param terminal The terminal to check for.
|
|
315
317
|
/// @return A flag indicating whether the project uses the terminal.
|
package/src/JBERC20.sol
CHANGED
|
@@ -15,10 +15,11 @@ import {IJBProjects} from "./interfaces/IJBProjects.sol";
|
|
|
15
15
|
import {IJBToken} from "./interfaces/IJBToken.sol";
|
|
16
16
|
import {IJBTokens} from "./interfaces/IJBTokens.sol";
|
|
17
17
|
|
|
18
|
-
/// @notice
|
|
19
|
-
///
|
|
20
|
-
///
|
|
21
|
-
/// @dev `
|
|
18
|
+
/// @notice The ERC-20 token implementation used by Juicebox projects. Includes ERC20Votes (governance delegation) and
|
|
19
|
+
/// ERC20Permit (gasless approvals). Deployed as a minimal clone via `JBController.deployERC20For` — once deployed,
|
|
20
|
+
/// holders can claim their internal credits into this transferable token.
|
|
21
|
+
/// @dev Only `JBTokens` can mint and burn. The project owner (via `SET_TOKEN_METADATA` permission) can rename the
|
|
22
|
+
/// token. Supports ERC-1271 signature validation for smart-contract wallets.
|
|
22
23
|
contract JBERC20 is ERC20Votes, ERC20Permit, JBPermissioned, IERC1271, IJBToken {
|
|
23
24
|
//*********************************************************************//
|
|
24
25
|
// --------------------------- custom errors ------------------------- //
|
|
@@ -6,7 +6,9 @@ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
|
6
6
|
|
|
7
7
|
import {IJBFeelessAddresses} from "./interfaces/IJBFeelessAddresses.sol";
|
|
8
8
|
|
|
9
|
-
/// @notice
|
|
9
|
+
/// @notice A registry of addresses exempt from the protocol's 2.5% fee. Feeless addresses don't incur fees on
|
|
10
|
+
/// payouts they receive, surplus allowance they use, or cash outs where they are the beneficiary. Managed by the
|
|
11
|
+
/// contract owner (typically the protocol multisig).
|
|
10
12
|
contract JBFeelessAddresses is Ownable, IJBFeelessAddresses, IERC165 {
|
|
11
13
|
//*********************************************************************//
|
|
12
14
|
// --------------------- public stored properties -------------------- //
|
|
@@ -30,8 +32,9 @@ contract JBFeelessAddresses is Ownable, IJBFeelessAddresses, IERC165 {
|
|
|
30
32
|
// ---------------------- external transactions ---------------------- //
|
|
31
33
|
//*********************************************************************//
|
|
32
34
|
|
|
33
|
-
/// @notice
|
|
34
|
-
///
|
|
35
|
+
/// @notice Add or remove an address from the fee-exempt list. Feeless addresses don't pay the 2.5% protocol fee
|
|
36
|
+
/// on payouts received, surplus allowance used, or cash outs where they're the beneficiary.
|
|
37
|
+
/// @dev Can only be called by this contract's owner (typically the protocol multisig).
|
|
35
38
|
/// @param addr The address to set as feeless or not feeless.
|
|
36
39
|
/// @param flag Whether the address should be feeless (`true`) or not feeless (`false`).
|
|
37
40
|
function setFeelessAddress(address addr, bool flag) external virtual override onlyOwner {
|
|
@@ -7,8 +7,12 @@ import {IJBFundAccessLimits} from "./interfaces/IJBFundAccessLimits.sol";
|
|
|
7
7
|
import {JBCurrencyAmount} from "./structs/JBCurrencyAmount.sol";
|
|
8
8
|
import {JBFundAccessLimitGroup} from "./structs/JBFundAccessLimitGroup.sol";
|
|
9
9
|
|
|
10
|
-
/// @notice
|
|
11
|
-
///
|
|
10
|
+
/// @notice Controls how much a project can withdraw from its terminals each funding cycle. Two types of limits:
|
|
11
|
+
/// **Payout limits** cap how much can be distributed to splits and the project owner. **Surplus allowances** cap how
|
|
12
|
+
/// much the project owner can pull from the surplus (funds above payout limits). Both reset each ruleset cycle.
|
|
13
|
+
/// @dev Limits are denominated in a currency (which may differ from the held token) and resolved at withdrawal time
|
|
14
|
+
/// via `JBPrices`. An empty `fundAccessLimitGroups` array means zero access (not unlimited) — use `type(uint224).max`
|
|
15
|
+
/// for unlimited.
|
|
12
16
|
contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
13
17
|
//*********************************************************************//
|
|
14
18
|
// --------------------------- custom errors ------------------------- //
|
|
@@ -61,10 +65,11 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
61
65
|
// ---------------------- external transactions ---------------------- //
|
|
62
66
|
//*********************************************************************//
|
|
63
67
|
|
|
64
|
-
/// @notice
|
|
65
|
-
///
|
|
66
|
-
///
|
|
67
|
-
///
|
|
68
|
+
/// @notice Configure how much a project can withdraw from each of its terminals during a ruleset. Payout limits
|
|
69
|
+
/// cap how much can be distributed to splits/owner; surplus allowances cap how much extra the owner can pull from
|
|
70
|
+
/// surplus. Both reset each funding cycle.
|
|
71
|
+
/// @dev Only a project's controller can set fund access limits (called during `queueRulesetsOf`).
|
|
72
|
+
/// @dev Limits within each group must be sorted by currency in strictly increasing order to prevent duplicates.
|
|
68
73
|
/// @param projectId The ID of the project whose fund access limits are being set.
|
|
69
74
|
/// @param rulesetId The ID of the ruleset that the limits will apply within.
|
|
70
75
|
/// @param fundAccessLimitGroups An array containing payout limits and surplus allowances for each payment terminal.
|
|
@@ -152,14 +157,15 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
152
157
|
// ------------------------- external views -------------------------- //
|
|
153
158
|
//*********************************************************************//
|
|
154
159
|
|
|
155
|
-
/// @notice
|
|
156
|
-
///
|
|
160
|
+
/// @notice Look up how much a project can distribute (via `sendPayoutsOf`) from a specific terminal and token,
|
|
161
|
+
/// denominated in a specific currency. Returns 0 if no limit is configured for that currency.
|
|
162
|
+
/// @dev The fixed point return amount uses the same number of decimals as the terminal.
|
|
157
163
|
/// @param projectId The project's ID.
|
|
158
164
|
/// @param rulesetId The ruleset's ID.
|
|
159
165
|
/// @param terminal The terminal the payout limit applies to.
|
|
160
166
|
/// @param token The token the payout limit applies to.
|
|
161
167
|
/// @param currency The currency the payout limit is denominated in.
|
|
162
|
-
/// @return payoutLimit The payout limit, as a fixed point number with the same number of decimals as the
|
|
168
|
+
/// @return payoutLimit The payout limit, as a fixed point number with the same number of decimals as the
|
|
163
169
|
/// terminal.
|
|
164
170
|
function payoutLimitOf(
|
|
165
171
|
uint256 projectId,
|
|
@@ -195,10 +201,9 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
195
201
|
}
|
|
196
202
|
}
|
|
197
203
|
|
|
198
|
-
/// @notice
|
|
199
|
-
///
|
|
200
|
-
///
|
|
201
|
-
/// @dev The fixed point `amount`s returned will use the same number of decimals as the `terminal`.
|
|
204
|
+
/// @notice Get all payout limits for a project's terminal and token during a ruleset. A project can have multiple
|
|
205
|
+
/// payout limits denominated in different currencies (e.g. 10,000 USD + 5 ETH). Each is enforced independently.
|
|
206
|
+
/// @dev The fixed point `amount`s returned use the same number of decimals as the terminal.
|
|
202
207
|
/// @param projectId The project's ID.
|
|
203
208
|
/// @param rulesetId The ruleset's ID.
|
|
204
209
|
/// @param terminal The terminal the payout limits apply to.
|
|
@@ -243,15 +248,16 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
243
248
|
}
|
|
244
249
|
}
|
|
245
250
|
|
|
246
|
-
/// @notice
|
|
247
|
-
///
|
|
251
|
+
/// @notice Look up how much a project's owner can withdraw from the surplus (via `useAllowanceOf`) from a specific
|
|
252
|
+
/// terminal and token, denominated in a specific currency. Returns 0 if no allowance is configured.
|
|
253
|
+
/// @dev The fixed point return amount uses the same number of decimals as the terminal.
|
|
248
254
|
/// @param projectId The project's ID.
|
|
249
255
|
/// @param rulesetId The ruleset's ID.
|
|
250
256
|
/// @param terminal The terminal the surplus allowance applies to.
|
|
251
257
|
/// @param token The token the surplus allowance applies to.
|
|
252
258
|
/// @param currency The currency that the surplus allowance is denominated in.
|
|
253
259
|
/// @return surplusAllowance The surplus allowance, as a fixed point number with the same number of decimals as the
|
|
254
|
-
///
|
|
260
|
+
/// terminal.
|
|
255
261
|
function surplusAllowanceOf(
|
|
256
262
|
uint256 projectId,
|
|
257
263
|
uint256 rulesetId,
|
|
@@ -287,11 +293,9 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
287
293
|
}
|
|
288
294
|
}
|
|
289
295
|
|
|
290
|
-
/// @notice
|
|
291
|
-
///
|
|
292
|
-
///
|
|
293
|
-
/// currency.
|
|
294
|
-
/// @dev The fixed point `amount`s returned will use the same number of decimals as the `terminal`.
|
|
296
|
+
/// @notice Get all surplus allowances for a project's terminal and token during a ruleset. Like payout limits, a
|
|
297
|
+
/// project can have multiple surplus allowances in different currencies, each enforced independently.
|
|
298
|
+
/// @dev The fixed point `amount`s returned use the same number of decimals as the terminal.
|
|
295
299
|
/// @param projectId The project's ID.
|
|
296
300
|
/// @param rulesetId The ruleset's ID.
|
|
297
301
|
/// @param terminal The terminal the surplus allowances apply to.
|