@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/src/JBMultiTerminal.sol
CHANGED
|
@@ -45,8 +45,13 @@ import {JBSplit} from "./structs/JBSplit.sol";
|
|
|
45
45
|
import {JBSplitHookContext} from "./structs/JBSplitHookContext.sol";
|
|
46
46
|
import {JBTokenAmount} from "./structs/JBTokenAmount.sol";
|
|
47
47
|
|
|
48
|
-
/// @notice
|
|
49
|
-
///
|
|
48
|
+
/// @notice The main entry point for all money movement in Juicebox. Handles payments (ETH or ERC-20), cash outs
|
|
49
|
+
/// (burning tokens to reclaim funds), payouts (distributing funds to splits), and surplus allowance withdrawals.
|
|
50
|
+
/// Charges a 2.5% protocol fee on outflows (held for 28 days before processing). Supports Permit2 for gasless
|
|
51
|
+
/// ERC-20 approvals.
|
|
52
|
+
/// @dev Each project can have multiple terminals for different tokens. The terminal delegates accounting to
|
|
53
|
+
/// `JBTerminalStore` and splits distribution to `JBSplits`. Fees are sent to project #1 (the fee beneficiary).
|
|
54
|
+
/// All external hook calls (pay hooks, cash-out hooks, split hooks) are wrapped in try-catch to prevent griefing.
|
|
50
55
|
contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
51
56
|
// A library that parses the packed ruleset metadata into a friendlier format.
|
|
52
57
|
using JBRulesetMetadataResolver for JBRuleset;
|
|
@@ -185,10 +190,10 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
185
190
|
// ---------------------- external transactions ---------------------- //
|
|
186
191
|
//*********************************************************************//
|
|
187
192
|
|
|
188
|
-
/// @notice
|
|
189
|
-
///
|
|
190
|
-
/// @dev Only
|
|
191
|
-
///
|
|
193
|
+
/// @notice Registers new tokens that this terminal can accept for a project. Once a token's accounting context is
|
|
194
|
+
/// added, the project can receive payments in that token.
|
|
195
|
+
/// @dev Only the project's owner, an operator with `ADD_ACCOUNTING_CONTEXTS` permission, or the project's
|
|
196
|
+
/// controller can call this.
|
|
192
197
|
/// @param projectId The ID of the project having to add accounting contexts for.
|
|
193
198
|
/// @param accountingContexts The accounting contexts to add.
|
|
194
199
|
function addAccountingContextsFor(
|
|
@@ -219,8 +224,9 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
219
224
|
}
|
|
220
225
|
}
|
|
221
226
|
|
|
222
|
-
/// @notice Adds funds to a project's balance without minting tokens.
|
|
223
|
-
///
|
|
227
|
+
/// @notice Adds funds to a project's balance without minting tokens. Useful for topping up a project or returning
|
|
228
|
+
/// funds. Can also unlock previously held fees by returning them to the project's balance.
|
|
229
|
+
/// @dev If `shouldReturnHeldFees` is true, the added amount offsets held fees proportionally.
|
|
224
230
|
/// @param projectId The ID of the project to add funds to the balance of.
|
|
225
231
|
/// @param amount The amount of tokens to add to the balance, as a fixed point number with the same number of
|
|
226
232
|
/// decimals as this terminal. If this is a native token terminal, this is ignored and `msg.value` is used instead.
|
|
@@ -251,10 +257,9 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
251
257
|
});
|
|
252
258
|
}
|
|
253
259
|
|
|
254
|
-
/// @notice
|
|
255
|
-
///
|
|
256
|
-
/// @dev Only
|
|
257
|
-
/// those tokens.
|
|
260
|
+
/// @notice Burns project tokens to reclaim a share of the project's surplus (determined by the bonding curve) or
|
|
261
|
+
/// to trigger custom logic through the ruleset's data hook and cash out hook.
|
|
262
|
+
/// @dev Only the token holder or an operator with `CASH_OUT_TOKENS` permission from that holder can call this.
|
|
258
263
|
/// @param holder The account whose tokens are being cashed out.
|
|
259
264
|
/// @param projectId The ID of the project the project tokens belong to.
|
|
260
265
|
/// @param cashOutCount The number of project tokens to cash out and burn, as a fixed point number with 18
|
|
@@ -563,7 +568,8 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
563
568
|
}
|
|
564
569
|
}
|
|
565
570
|
|
|
566
|
-
/// @notice Pay a project with tokens.
|
|
571
|
+
/// @notice Pay a project with tokens. The project's current ruleset determines how many project tokens the
|
|
572
|
+
/// beneficiary receives in return.
|
|
567
573
|
/// @param projectId The ID of the project being paid.
|
|
568
574
|
/// @param amount The amount of terminal tokens being received, as a fixed point number with the same number of
|
|
569
575
|
/// decimals as this terminal. If this terminal's token is native, this is ignored and `msg.value` is used in its
|
|
@@ -622,19 +628,13 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
622
628
|
_checkMin({value: beneficiaryTokenCount, min: minReturnedTokens});
|
|
623
629
|
}
|
|
624
630
|
|
|
625
|
-
/// @notice
|
|
626
|
-
///
|
|
627
|
-
///
|
|
628
|
-
/// @dev
|
|
629
|
-
///
|
|
630
|
-
///
|
|
631
|
-
///
|
|
632
|
-
/// (e.g. the fee terminal rejects the payment), the catch block calls `_recordAddedBalanceFor` to credit the fee
|
|
633
|
-
/// amount back to the project. This credit is backed by the tokens that failed to transfer out. No phantom balance
|
|
634
|
-
/// is created because the tokens never left.
|
|
635
|
-
/// @dev The index-increment-before-`_processFee` pattern is intentional: locked (not-yet-unlocked) fees are skipped
|
|
636
|
-
/// via the `unlockTimestamp` check, and advancing the index before the external call prevents reentrancy from
|
|
637
|
-
/// reprocessing the same fee entry.
|
|
631
|
+
/// @notice Processes held fees for a project, sending them to the protocol's fee project. Fees are held for 28 days
|
|
632
|
+
/// after a payout — processing them finalizes the fee payment.
|
|
633
|
+
/// @dev Only processes fees whose `unlockTimestamp` has passed. Stops early if it encounters a still-locked fee.
|
|
634
|
+
/// @dev Reentrancy-safe: re-reads `_nextHeldFeeIndexOf` from storage each iteration and advances the index before
|
|
635
|
+
/// the external `_processFee` call, preventing double-processing.
|
|
636
|
+
/// @dev If `_processFee` reverts (fee terminal rejects), the fee amount is returned to the project's balance
|
|
637
|
+
/// (forgiven, not retried). A `FeeReverted` event is emitted for off-chain observability.
|
|
638
638
|
/// @param projectId The ID of the project to process held fees for.
|
|
639
639
|
/// @param token The token to process held fees for.
|
|
640
640
|
/// @param count The number of fees to process.
|
|
@@ -657,6 +657,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
657
657
|
|
|
658
658
|
// Can't process fees that aren't yet unlocked. Fees unlock sequentially in the array, so nothing left to do
|
|
659
659
|
// if the current fee isn't yet unlocked.
|
|
660
|
+
// forge-lint: disable-next-line(block-timestamp)
|
|
660
661
|
if (heldFee.unlockTimestamp > block.timestamp) break;
|
|
661
662
|
|
|
662
663
|
// Delete the entry and advance the index *before* the external call. This is intentional:
|
|
@@ -694,15 +695,12 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
694
695
|
}
|
|
695
696
|
}
|
|
696
697
|
|
|
697
|
-
/// @notice
|
|
698
|
-
/// payout limit.
|
|
699
|
-
/// @dev If
|
|
700
|
-
///
|
|
701
|
-
/// @dev
|
|
702
|
-
///
|
|
703
|
-
/// be used to incentivize calling this function.
|
|
704
|
-
/// @dev payouts sent to addresses which aren't feeless incur the protocol fee.
|
|
705
|
-
/// @dev Payouts a projects don't incur fees if its terminal is feeless.
|
|
698
|
+
/// @notice Distributes funds from a project's balance to its payout split recipients, up to the current ruleset's
|
|
699
|
+
/// payout limit. Anyone can call this on behalf of any project.
|
|
700
|
+
/// @dev If splits don't add up to 100%, the remainder goes to the project owner. A wildcard split (no hook,
|
|
701
|
+
/// projectId, or beneficiary) sends its share to `msg.sender` — useful for incentivizing the call.
|
|
702
|
+
/// @dev Payouts to non-feeless addresses incur the 2.5% protocol fee. Projects whose terminal is feeless are
|
|
703
|
+
/// exempt.
|
|
706
704
|
/// @param projectId The ID of the project having its payouts sent.
|
|
707
705
|
/// @param token The token being sent.
|
|
708
706
|
/// @param amount The total number of terminal tokens to send, as a fixed point number with same number of decimals
|
|
@@ -730,10 +728,10 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
730
728
|
_checkMin({value: amountPaidOut, min: minTokensPaidOut});
|
|
731
729
|
}
|
|
732
730
|
|
|
733
|
-
/// @notice
|
|
734
|
-
///
|
|
735
|
-
///
|
|
736
|
-
/// @dev Incurs the protocol fee unless the caller is a feeless address.
|
|
731
|
+
/// @notice Withdraws funds from a project's surplus (beyond what's needed for payouts) up to the current ruleset's
|
|
732
|
+
/// surplus allowance. Sent directly to a beneficiary address rather than through splits.
|
|
733
|
+
/// @dev Only the project's owner or an operator with `USE_ALLOWANCE` permission can call this.
|
|
734
|
+
/// @dev Incurs the 2.5% protocol fee unless the caller is a feeless address.
|
|
737
735
|
/// @param projectId The ID of the project to use the surplus allowance of.
|
|
738
736
|
/// @param token The token being paid out from the surplus.
|
|
739
737
|
/// @param amount The amount of terminal tokens to use from the project's current surplus allowance, as a fixed
|
|
@@ -787,8 +785,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
787
785
|
// ------------------------- external views -------------------------- //
|
|
788
786
|
//*********************************************************************//
|
|
789
787
|
|
|
790
|
-
/// @notice
|
|
791
|
-
/// @dev See the `JBAccountingContext` struct for more information.
|
|
788
|
+
/// @notice Returns the accounting context (decimals, currency) for a specific token that a project accepts.
|
|
792
789
|
/// @param projectId The ID of the project to get token accounting context of.
|
|
793
790
|
/// @param token The token to check the accounting context of.
|
|
794
791
|
/// @return The token's accounting context for the token.
|
|
@@ -804,15 +801,16 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
804
801
|
return STORE.accountingContextOf({terminal: address(this), projectId: projectId, token: token});
|
|
805
802
|
}
|
|
806
803
|
|
|
807
|
-
/// @notice
|
|
804
|
+
/// @notice Returns accounting contexts for all tokens a project currently accepts through this terminal.
|
|
808
805
|
/// @param projectId The ID of the project to get the accepted tokens of.
|
|
809
806
|
/// @return tokenContexts The accounting contexts of the accepted tokens.
|
|
810
807
|
function accountingContextsOf(uint256 projectId) external view override returns (JBAccountingContext[] memory) {
|
|
811
808
|
return STORE.accountingContextsOf({terminal: address(this), projectId: projectId});
|
|
812
809
|
}
|
|
813
810
|
|
|
814
|
-
/// @notice
|
|
815
|
-
///
|
|
811
|
+
/// @notice Returns the project's current surplus in this terminal, converted to a specified currency. The surplus
|
|
812
|
+
/// is the balance minus what's needed for payout limits.
|
|
813
|
+
/// @dev If `tokens` is empty, includes all tokens the project accepts.
|
|
816
814
|
/// @param projectId The ID of the project to get the current surplus of.
|
|
817
815
|
/// @param tokens The tokens to include in the surplus calculation. If empty, all tokens are included.
|
|
818
816
|
/// @param decimals The number of decimals to include in the fixed point returned value.
|
|
@@ -837,9 +835,10 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
837
835
|
});
|
|
838
836
|
}
|
|
839
837
|
|
|
840
|
-
/// @notice
|
|
841
|
-
///
|
|
842
|
-
/// @dev Held fees can be
|
|
838
|
+
/// @notice Returns the fees currently being held for a project. Fees are held for 28 days after a payout before
|
|
839
|
+
/// they can be processed (sent to the fee project).
|
|
840
|
+
/// @dev Held fees can be returned to the project by calling `addToBalanceOf` with `shouldReturnHeldFees = true`
|
|
841
|
+
/// before the 28-day lock expires.
|
|
843
842
|
/// @param projectId The ID of the project that is holding fees.
|
|
844
843
|
/// @param token The token that the fees are held in.
|
|
845
844
|
/// @param count The maximum number of held fees to return.
|
|
@@ -878,7 +877,8 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
878
877
|
}
|
|
879
878
|
}
|
|
880
879
|
|
|
881
|
-
/// @notice Simulates
|
|
880
|
+
/// @notice Simulates a cash out without modifying state — use this to preview how many tokens a holder would
|
|
881
|
+
/// reclaim.
|
|
882
882
|
/// @param holder The address whose tokens are being cashed out.
|
|
883
883
|
/// @param projectId The ID of the project whose tokens are being cashed out.
|
|
884
884
|
/// @param cashOutCount The number of project tokens to cash out.
|
|
@@ -919,7 +919,9 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
919
919
|
});
|
|
920
920
|
}
|
|
921
921
|
|
|
922
|
-
/// @notice Simulates
|
|
922
|
+
/// @notice Simulates a payment without modifying state — use this to preview how many project tokens a payer
|
|
923
|
+
/// would
|
|
924
|
+
/// receive.
|
|
923
925
|
/// @param projectId The ID of the project being paid.
|
|
924
926
|
/// @param token The token being paid in.
|
|
925
927
|
/// @param amount The amount of tokens being paid.
|
|
@@ -1586,7 +1588,8 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
1586
1588
|
}
|
|
1587
1589
|
}
|
|
1588
1590
|
|
|
1589
|
-
/// @notice
|
|
1591
|
+
/// @notice Internal implementation of payment logic. Records the payment in the store, mints tokens via the
|
|
1592
|
+
/// controller, and fulfills any pay hook specifications from the data hook.
|
|
1590
1593
|
/// @param projectId The ID of the project being paid.
|
|
1591
1594
|
/// @param token The address of the token which the project is being paid with.
|
|
1592
1595
|
/// @param amount The amount of terminal tokens being received, as a fixed point number with the same number of
|
package/src/JBPermissions.sol
CHANGED
|
@@ -7,8 +7,11 @@ import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol"
|
|
|
7
7
|
import {IJBPermissions} from "./interfaces/IJBPermissions.sol";
|
|
8
8
|
import {JBPermissionsData} from "./structs/JBPermissionsData.sol";
|
|
9
9
|
|
|
10
|
-
/// @notice
|
|
11
|
-
///
|
|
10
|
+
/// @notice The permission system for Juicebox. Any address can authorize another address (an "operator") to perform
|
|
11
|
+
/// specific actions on its behalf — like queuing rulesets, distributing payouts, or managing terminals.
|
|
12
|
+
/// @dev Permissions are stored as a packed `uint256` bitmap: each of the 256 bits represents one permission's
|
|
13
|
+
/// on/off state. Project ID 0 is a wildcard that grants an operator access across all projects — use with caution.
|
|
14
|
+
/// @dev The ROOT permission (ID 1) implicitly grants every other permission for the scoped project.
|
|
12
15
|
contract JBPermissions is ERC2771Context, IJBPermissions {
|
|
13
16
|
//*********************************************************************//
|
|
14
17
|
// --------------------------- custom errors ------------------------- //
|
|
@@ -23,19 +26,19 @@ contract JBPermissions is ERC2771Context, IJBPermissions {
|
|
|
23
26
|
// ------------------------- public constants ------------------------ //
|
|
24
27
|
//*********************************************************************//
|
|
25
28
|
|
|
26
|
-
/// @notice The project ID
|
|
29
|
+
/// @notice The project ID that acts as a wildcard — granting the operator permissions across all projects owned
|
|
30
|
+
/// by
|
|
31
|
+
/// the account. Setting permissions for project ID 0 is powerful and should be done carefully.
|
|
27
32
|
uint256 public constant override WILDCARD_PROJECT_ID = 0;
|
|
28
33
|
|
|
29
34
|
//*********************************************************************//
|
|
30
35
|
// --------------------- public stored properties -------------------- //
|
|
31
36
|
//*********************************************************************//
|
|
32
37
|
|
|
33
|
-
/// @notice The
|
|
34
|
-
/// @dev
|
|
35
|
-
///
|
|
36
|
-
///
|
|
37
|
-
/// @dev Permissions are stored in a packed `uint256`. Each of the 256 bits represents the on/off state of a
|
|
38
|
-
/// permission. Applications can specify the significance of each permission ID.
|
|
38
|
+
/// @notice The packed permission bitmap that an account has granted to an operator for a specific project.
|
|
39
|
+
/// @dev Each bit in the returned `uint256` corresponds to a permission ID (0–255). A `1` bit means that
|
|
40
|
+
/// permission
|
|
41
|
+
/// is granted. See `JBPermissionIds` for the meaning of each ID.
|
|
39
42
|
/// @custom:param operator The address of the operator.
|
|
40
43
|
/// @custom:param account The address of the account being operated on behalf of.
|
|
41
44
|
/// @custom:param projectId The project ID the permissions are scoped to. An ID of 0 grants permissions across all
|
|
@@ -55,14 +58,12 @@ contract JBPermissions is ERC2771Context, IJBPermissions {
|
|
|
55
58
|
// ---------------------- external transactions ---------------------- //
|
|
56
59
|
//*********************************************************************//
|
|
57
60
|
|
|
58
|
-
/// @notice
|
|
59
|
-
/// @dev Only the
|
|
60
|
-
///
|
|
61
|
-
///
|
|
62
|
-
///
|
|
63
|
-
///
|
|
64
|
-
/// @param account The account setting its operators' permissions.
|
|
65
|
-
/// @param permissionsData The data which specifies the permissions the operator is being given.
|
|
61
|
+
/// @notice Grant or revoke permissions for an operator on a specific project.
|
|
62
|
+
/// @dev Only the account itself can set permissions without restriction. A ROOT operator on a specific project can
|
|
63
|
+
/// set non-ROOT permissions for that same project on the account's behalf, but cannot grant ROOT or set wildcard
|
|
64
|
+
/// (project ID 0) permissions — preventing privilege escalation.
|
|
65
|
+
/// @param account The account whose operator permissions are being configured.
|
|
66
|
+
/// @param permissionsData The operator address, project scope, and permission IDs to set.
|
|
66
67
|
function setPermissionsFor(address account, JBPermissionsData calldata permissionsData) external override {
|
|
67
68
|
// Pack the permission IDs into a uint256.
|
|
68
69
|
uint256 packed = _packedPermissions(permissionsData.permissionIds);
|
|
@@ -113,16 +114,14 @@ contract JBPermissions is ERC2771Context, IJBPermissions {
|
|
|
113
114
|
// ------------------------- external views -------------------------- //
|
|
114
115
|
//*********************************************************************//
|
|
115
116
|
|
|
116
|
-
/// @notice Check
|
|
117
|
-
/// @param operator The
|
|
118
|
-
/// @param account The account
|
|
119
|
-
/// @param projectId The project ID
|
|
120
|
-
/// @param permissionIds
|
|
121
|
-
/// @param includeRoot
|
|
122
|
-
///
|
|
123
|
-
/// @
|
|
124
|
-
/// specified permission on the wildcard project ID.
|
|
125
|
-
/// @return A flag indicating whether the operator has all specified permissions.
|
|
117
|
+
/// @notice Check whether an operator has *all* of the specified permissions for an account and project.
|
|
118
|
+
/// @param operator The address to check permissions for.
|
|
119
|
+
/// @param account The account that granted (or didn't grant) the permissions.
|
|
120
|
+
/// @param projectId The project ID to check within. Pass 0 to check the wildcard scope directly.
|
|
121
|
+
/// @param permissionIds The permission IDs that must all be present.
|
|
122
|
+
/// @param includeRoot If `true`, returns `true` immediately when the operator has the ROOT permission.
|
|
123
|
+
/// @param includeWildcardProjectId If `true`, also checks wildcard (project 0) permissions as a fallback.
|
|
124
|
+
/// @return Whether the operator holds every requested permission.
|
|
126
125
|
function hasPermissions(
|
|
127
126
|
address operator,
|
|
128
127
|
address account,
|
|
@@ -187,16 +186,14 @@ contract JBPermissions is ERC2771Context, IJBPermissions {
|
|
|
187
186
|
// -------------------------- public views --------------------------- //
|
|
188
187
|
//*********************************************************************//
|
|
189
188
|
|
|
190
|
-
/// @notice Check
|
|
191
|
-
/// @param operator The
|
|
192
|
-
/// @param account The account
|
|
193
|
-
/// @param projectId The project ID
|
|
194
|
-
/// @param permissionId The permission ID to
|
|
195
|
-
/// @param includeRoot
|
|
196
|
-
///
|
|
197
|
-
/// @
|
|
198
|
-
/// specified permission on the wildcard project ID.
|
|
199
|
-
/// @return A flag indicating whether the operator has the specified permission.
|
|
189
|
+
/// @notice Check whether an operator has a single permission for an account and project.
|
|
190
|
+
/// @param operator The address to check.
|
|
191
|
+
/// @param account The account that granted (or didn't grant) the permission.
|
|
192
|
+
/// @param projectId The project ID to check within. Pass 0 to check the wildcard scope directly.
|
|
193
|
+
/// @param permissionId The specific permission ID to look for (0–255).
|
|
194
|
+
/// @param includeRoot If `true`, returns `true` immediately when the operator has the ROOT permission.
|
|
195
|
+
/// @param includeWildcardProjectId If `true`, also checks wildcard (project 0) permissions as a fallback.
|
|
196
|
+
/// @return Whether the operator holds the requested permission.
|
|
200
197
|
function hasPermission(
|
|
201
198
|
address operator,
|
|
202
199
|
address account,
|
package/src/JBPrices.sol
CHANGED
|
@@ -13,12 +13,13 @@ import {IJBPriceFeed} from "./interfaces/IJBPriceFeed.sol";
|
|
|
13
13
|
import {IJBPrices} from "./interfaces/IJBPrices.sol";
|
|
14
14
|
import {IJBProjects} from "./interfaces/IJBProjects.sol";
|
|
15
15
|
|
|
16
|
-
/// @notice
|
|
17
|
-
///
|
|
18
|
-
///
|
|
19
|
-
///
|
|
20
|
-
///
|
|
21
|
-
///
|
|
16
|
+
/// @notice Provides currency conversion for the protocol. When a project's payout limits or surplus allowances are
|
|
17
|
+
/// denominated in a currency different from the token held in its terminal (e.g. USD limits with ETH held), this
|
|
18
|
+
/// contract resolves the exchange rate via registered price feeds (typically Chainlink oracles).
|
|
19
|
+
/// @dev Price feeds are immutable once set — they cannot be replaced or removed. This protects against oracle
|
|
20
|
+
/// manipulation via admin-key attacks. If a feed is misconfigured, operations using that pair will revert (DoS, not
|
|
21
|
+
/// fund loss). The inverse of any registered feed is auto-calculated. Projects can have their own feeds; project ID 0
|
|
22
|
+
/// holds protocol-wide defaults.
|
|
22
23
|
contract JBPrices is JBControlled, JBPermissioned, ERC2771Context, Ownable, IJBPrices {
|
|
23
24
|
//*********************************************************************//
|
|
24
25
|
// --------------------------- custom errors ------------------------- //
|
|
@@ -85,13 +86,14 @@ contract JBPrices is JBControlled, JBPermissioned, ERC2771Context, Ownable, IJBP
|
|
|
85
86
|
// ---------------------- external transactions ---------------------- //
|
|
86
87
|
//*********************************************************************//
|
|
87
88
|
|
|
88
|
-
/// @notice
|
|
89
|
-
///
|
|
90
|
-
///
|
|
91
|
-
///
|
|
92
|
-
///
|
|
93
|
-
/// @
|
|
94
|
-
/// feed.
|
|
89
|
+
/// @notice Register a price feed that provides the exchange rate between two currencies. For example, registering
|
|
90
|
+
/// an ETH/USD feed allows payout limits denominated in USD to be enforced against ETH balances.
|
|
91
|
+
/// @dev Price feeds are immutable — once set for a currency pair, they cannot be replaced or removed. This
|
|
92
|
+
/// prevents
|
|
93
|
+
/// admin-key oracle manipulation. The inverse rate is auto-calculated, so registering A→B also provides B→A.
|
|
94
|
+
/// @dev Pass `projectId` = 0 to set a protocol-wide default (owner only). Non-zero project IDs require controller
|
|
95
|
+
/// authorization. A default feed for a pair blocks per-project overrides for that same pair.
|
|
96
|
+
/// @param projectId The ID of the project to add a feed for. Pass 0 for a protocol-wide default.
|
|
95
97
|
/// @param pricingCurrency The currency the feed's output price is in terms of.
|
|
96
98
|
/// @param unitCurrency The currency being priced by the feed.
|
|
97
99
|
/// @param feed The address of the price feed to add.
|
|
@@ -156,11 +158,14 @@ contract JBPrices is JBControlled, JBPermissioned, ERC2771Context, Ownable, IJBP
|
|
|
156
158
|
// -------------------------- public views --------------------------- //
|
|
157
159
|
//*********************************************************************//
|
|
158
160
|
|
|
159
|
-
/// @notice
|
|
160
|
-
///
|
|
161
|
-
///
|
|
162
|
-
/// @
|
|
163
|
-
///
|
|
161
|
+
/// @notice Convert between currencies — returns how much of `pricingCurrency` one unit of `unitCurrency` is
|
|
162
|
+
/// worth.
|
|
163
|
+
/// For example, `pricePerUnitOf(id, USD, ETH, 18)` returns the USD price of 1 ETH with 18 decimals.
|
|
164
|
+
/// @dev Lookup order: project-specific feed → inverse of project feed → default feed (project 0) → inverse of
|
|
165
|
+
/// default. Reverts with `JBPrices_PriceFeedNotFound` if no feed exists in any direction.
|
|
166
|
+
/// @param projectId The ID of the project to check the feed for. Falls back to project 0 (protocol defaults).
|
|
167
|
+
/// @param pricingCurrency The currency the result is denominated in.
|
|
168
|
+
/// @param unitCurrency The currency being priced.
|
|
164
169
|
/// @param decimals The number of decimals the returned fixed point price should include.
|
|
165
170
|
/// @return The `pricingCurrency` price of 1 `unitCurrency`, as a fixed point number with the specified number of
|
|
166
171
|
/// decimals.
|
package/src/JBProjects.sol
CHANGED
|
@@ -9,8 +9,9 @@ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
|
9
9
|
import {IJBProjects} from "./interfaces/IJBProjects.sol";
|
|
10
10
|
import {IJBTokenUriResolver} from "./interfaces/IJBTokenUriResolver.sol";
|
|
11
11
|
|
|
12
|
-
/// @notice
|
|
13
|
-
///
|
|
12
|
+
/// @notice Each Juicebox project is an ERC-721 NFT. Whoever holds the NFT owns the project and can configure its
|
|
13
|
+
/// rulesets, terminals, and permissions. Projects are created with `createFor` and the resulting token ID is used as
|
|
14
|
+
/// the project's ID across the entire protocol.
|
|
14
15
|
contract JBProjects is ERC721, ERC2771Context, Ownable, IJBProjects {
|
|
15
16
|
//*********************************************************************//
|
|
16
17
|
// --------------------- public stored properties -------------------- //
|
|
@@ -50,7 +51,9 @@ contract JBProjects is ERC721, ERC2771Context, Ownable, IJBProjects {
|
|
|
50
51
|
// ---------------------- external transactions ---------------------- //
|
|
51
52
|
//*********************************************************************//
|
|
52
53
|
|
|
53
|
-
/// @notice
|
|
54
|
+
/// @notice Set the contract that resolves project NFT metadata (the `tokenURI`). This controls what artwork and
|
|
55
|
+
/// JSON metadata is returned for each project's ERC-721 token.
|
|
56
|
+
/// @dev Only this contract's owner can change the resolver.
|
|
54
57
|
/// @param resolver The address of the new resolver.
|
|
55
58
|
function setTokenUriResolver(IJBTokenUriResolver resolver) external override onlyOwner {
|
|
56
59
|
// Store the new resolver.
|