@bananapus/core-v6 0.0.81 → 0.0.83
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/README.md +11 -11
- package/package.json +3 -3
- package/references/entrypoints.md +1 -1
- package/references/types-errors-events.md +8 -8
- package/src/JBChainlinkV3PriceFeed.sol +5 -0
- package/src/JBChainlinkV3SequencerPriceFeed.sol +3 -0
- package/src/JBController.sol +41 -17
- package/src/JBDirectory.sol +11 -4
- package/src/JBERC20.sol +3 -0
- package/src/JBFeelessAddresses.sol +3 -0
- package/src/JBFundAccessLimits.sol +5 -0
- package/src/JBMultiTerminal.sol +45 -35
- package/src/JBPermissions.sol +8 -5
- package/src/JBPrices.sol +9 -0
- package/src/JBProjects.sol +5 -0
- package/src/JBRulesets.sol +22 -16
- package/src/JBSplits.sol +5 -0
- package/src/JBTerminalStore.sol +34 -13
- package/src/JBTokens.sol +21 -0
- package/src/abstract/JBControlled.sol +1 -0
- package/src/abstract/JBPermissioned.sol +2 -3
- package/src/enums/JBApprovalStatus.sol +6 -6
- package/src/interfaces/IJBCashOutTerminal.sol +1 -2
- package/src/interfaces/IJBController.sol +2 -2
- package/src/interfaces/IJBFeelessAddresses.sol +1 -2
- package/src/interfaces/IJBFeelessHook.sol +2 -2
- package/src/libraries/JBMetadataResolver.sol +9 -1
- package/src/libraries/JBPayoutSplitGroupLib.sol +14 -0
- package/src/periphery/JBMatchingPriceFeed.sol +3 -1
- package/src/structs/JBAccountingContext.sol +1 -2
- package/src/structs/JBAfterCashOutRecordedContext.sol +1 -2
- package/src/structs/JBCashOutHookSpecification.sol +1 -2
- package/src/structs/JBPayHookSpecification.sol +1 -2
- package/src/structs/JBSplit.sol +1 -2
package/src/JBMultiTerminal.sol
CHANGED
|
@@ -66,18 +66,43 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
66
66
|
// --------------------------- custom errors ------------------------- //
|
|
67
67
|
//*********************************************************************//
|
|
68
68
|
|
|
69
|
+
/// @notice Thrown when no terminal can be found to pay a fee in the given token.
|
|
69
70
|
error JBMultiTerminal_FeeTerminalNotFound(address token);
|
|
71
|
+
|
|
72
|
+
/// @notice Thrown when a payout split routes back into the project that is paying out.
|
|
70
73
|
error JBMultiTerminal_MintNotAllowed(uint256 projectId, address terminal);
|
|
74
|
+
|
|
75
|
+
/// @notice Thrown when native value is sent with an operation that does not accept it.
|
|
71
76
|
error JBMultiTerminal_NoMsgValueAllowed(uint256 value);
|
|
77
|
+
|
|
78
|
+
/// @notice Thrown when a value exceeds the allowed maximum.
|
|
72
79
|
error JBMultiTerminal_OverflowAlert(uint256 value, uint256 limit);
|
|
80
|
+
|
|
81
|
+
/// @notice Thrown when the Permit2 allowance is less than the amount being paid.
|
|
73
82
|
error JBMultiTerminal_PermitAllowanceNotEnough(uint256 amount, uint256 allowance);
|
|
83
|
+
|
|
84
|
+
/// @notice Thrown when no terminal can be found to pay a recipient project's split in the given token.
|
|
74
85
|
error JBMultiTerminal_RecipientProjectTerminalNotFound(uint256 projectId, address token);
|
|
86
|
+
|
|
87
|
+
/// @notice Thrown when a token transfer reenters during a balance-delta measurement.
|
|
75
88
|
error JBMultiTerminal_ReentrantTokenTransfer(address token);
|
|
89
|
+
|
|
90
|
+
/// @notice Thrown when a split hook does not support the `IJBSplitHook` interface.
|
|
76
91
|
error JBMultiTerminal_SplitHookInvalid(IJBSplitHook hook);
|
|
92
|
+
|
|
93
|
+
/// @notice Thrown when an approved temporary allowance was not fully consumed by the spender.
|
|
77
94
|
error JBMultiTerminal_TemporaryAllowanceNotConsumed(address token, address spender, uint256 allowance);
|
|
95
|
+
|
|
96
|
+
/// @notice Thrown when migrating a terminal to itself.
|
|
78
97
|
error JBMultiTerminal_TerminalMigrationToSelf(uint256 projectId, address token);
|
|
98
|
+
|
|
99
|
+
/// @notice Thrown when the terminal being migrated to does not accept the same token.
|
|
79
100
|
error JBMultiTerminal_TerminalTokensIncompatible(uint256 projectId, address token, IJBTerminal terminal);
|
|
101
|
+
|
|
102
|
+
/// @notice Thrown when the terminal does not accept the given token.
|
|
80
103
|
error JBMultiTerminal_TokenNotAccepted(address token);
|
|
104
|
+
|
|
105
|
+
/// @notice Thrown when a value is less than the required minimum.
|
|
81
106
|
error JBMultiTerminal_UnderMin(uint256 value, uint256 min);
|
|
82
107
|
|
|
83
108
|
//*********************************************************************//
|
|
@@ -109,7 +134,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
109
134
|
/// @notice The contract that stores and manages the terminal's data.
|
|
110
135
|
IJBTerminalStore public immutable override STORE;
|
|
111
136
|
|
|
112
|
-
/// @notice The contract
|
|
137
|
+
/// @notice The contract that manages token minting and burning.
|
|
113
138
|
IJBTokens public immutable override TOKENS;
|
|
114
139
|
|
|
115
140
|
//*********************************************************************//
|
|
@@ -162,8 +187,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
162
187
|
// -------------------------- constructor ---------------------------- //
|
|
163
188
|
//*********************************************************************//
|
|
164
189
|
|
|
165
|
-
/// @param feelessAddresses A contract that stores addresses that shouldn't incur fees
|
|
166
|
-
/// from.
|
|
190
|
+
/// @param feelessAddresses A contract that stores addresses that shouldn't incur fees on payments to or from them.
|
|
167
191
|
/// @param permissions A contract storing permissions.
|
|
168
192
|
/// @param projects A contract which mints ERC-721s that represent project ownership and transfers.
|
|
169
193
|
/// @param splits A contract that stores splits for each project.
|
|
@@ -235,9 +259,8 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
235
259
|
/// @dev If `shouldReturnHeldFees` is true, the added amount offsets held fees proportionally.
|
|
236
260
|
/// @param projectId The ID of the project to add funds to the balance of.
|
|
237
261
|
/// @param token The terminal token being added (the ERC-20, or `JBConstants.NATIVE_TOKEN` for native).
|
|
238
|
-
/// @param amount The amount of
|
|
239
|
-
///
|
|
240
|
-
/// `msg.value` is used instead.
|
|
262
|
+
/// @param amount The amount of terminal `token` to add, as a fixed point number using the token accounting
|
|
263
|
+
/// context's decimals. If `token` is the native token, this argument is ignored and `msg.value` is used instead.
|
|
241
264
|
/// @param shouldReturnHeldFees If true, return held fees proportional to the amount added.
|
|
242
265
|
/// @param memo A memo to pass along to the emitted event.
|
|
243
266
|
/// @param metadata Extra data to pass along to the emitted event.
|
|
@@ -279,8 +302,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
279
302
|
/// context. If fewer terminal tokens would be reclaimed, the cash out is reverted.
|
|
280
303
|
/// @param beneficiary The address to send the reclaimed terminal tokens to, and to pass along to the ruleset's
|
|
281
304
|
/// data hook and cash out hooks if applicable.
|
|
282
|
-
/// @param metadata Bytes to send
|
|
283
|
-
/// applicable.
|
|
305
|
+
/// @param metadata Bytes to send to the emitted event, data hook, and cash out hooks, if applicable.
|
|
284
306
|
/// @return reclaimAmount The amount of **terminal tokens** sent to `beneficiary` in exchange for the burned project
|
|
285
307
|
/// tokens, as a fixed point number with the same number of decimals as the terminal token's accounting context.
|
|
286
308
|
function cashOutTokensOf(
|
|
@@ -627,9 +649,8 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
627
649
|
/// `msg.value` is used in its place.
|
|
628
650
|
/// @param beneficiary The address to mint project tokens to, and to pass along to the ruleset's data hook and pay
|
|
629
651
|
/// hook if applicable.
|
|
630
|
-
/// @param minReturnedTokens The minimum
|
|
631
|
-
///
|
|
632
|
-
/// reverted.
|
|
652
|
+
/// @param minReturnedTokens The minimum project tokens the beneficiary must receive for the payment to succeed, as
|
|
653
|
+
/// a fixed point number with 18 decimals. If fewer project tokens would be minted, the payment is reverted.
|
|
633
654
|
/// @param memo A memo to pass along to the emitted event.
|
|
634
655
|
/// @param metadata Bytes to pass along to the emitted event, as well as the data hook and pay hook if applicable.
|
|
635
656
|
/// @return beneficiaryTokenCount The number of **project tokens** minted to `beneficiary`, as a fixed point number
|
|
@@ -755,18 +776,15 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
755
776
|
/// payout limit. Anyone can call this on behalf of any project.
|
|
756
777
|
/// @dev If splits don't add up to 100%, the remainder goes to the project owner. A wildcard split (no hook,
|
|
757
778
|
/// projectId, or beneficiary) sends its share to `msg.sender` — useful for incentivizing the call.
|
|
758
|
-
/// @dev Payouts to non-feeless addresses incur the 2.5% protocol fee
|
|
759
|
-
/// exempt.
|
|
779
|
+
/// @dev Payouts to non-feeless addresses incur the 2.5% protocol fee; feeless project terminals are exempt.
|
|
760
780
|
/// @param projectId The ID of the project having its payouts sent.
|
|
761
781
|
/// @param token The token to send.
|
|
762
782
|
/// @param amount The total number of terminal tokens to send, as a fixed point number with the same number of
|
|
763
783
|
/// decimals as the token's accounting context.
|
|
764
784
|
/// @param currency The expected currency of the payouts. Must match the currency of one of the
|
|
765
785
|
/// project's current ruleset's payout limits.
|
|
766
|
-
/// @param minTokensPaidOut The minimum
|
|
767
|
-
///
|
|
768
|
-
/// as the token's accounting context. If the amount of tokens paid out would be less than this amount, the send is
|
|
769
|
-
/// reverted.
|
|
786
|
+
/// @param minTokensPaidOut The minimum terminal-token value of `amount`, if expressed in the token accounting
|
|
787
|
+
/// context currency. If the payout would be less than this amount, the send is reverted.
|
|
770
788
|
/// @return amountPaidOut The total amount paid out.
|
|
771
789
|
function sendPayoutsOf(
|
|
772
790
|
uint256 projectId,
|
|
@@ -921,8 +939,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
921
939
|
});
|
|
922
940
|
}
|
|
923
941
|
|
|
924
|
-
/// @notice Simulates a cash out without modifying state
|
|
925
|
-
/// reclaim.
|
|
942
|
+
/// @notice Simulates a cash out without modifying state to preview how many tokens a holder would reclaim.
|
|
926
943
|
/// @param holder The address cashing out tokens.
|
|
927
944
|
/// @param projectId The ID of the project cashing out tokens.
|
|
928
945
|
/// @param cashOutCount The number of project tokens to cash out.
|
|
@@ -963,9 +980,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
963
980
|
});
|
|
964
981
|
}
|
|
965
982
|
|
|
966
|
-
/// @notice Simulates a payment without modifying state
|
|
967
|
-
/// would
|
|
968
|
-
/// receive.
|
|
983
|
+
/// @notice Simulates a payment without modifying state to preview the project tokens a payer would receive.
|
|
969
984
|
/// @param projectId The ID of the project to pay.
|
|
970
985
|
/// @param token The token to pay with.
|
|
971
986
|
/// @param amount The amount of tokens to pay.
|
|
@@ -1175,19 +1190,16 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
1175
1190
|
}
|
|
1176
1191
|
}
|
|
1177
1192
|
|
|
1178
|
-
/// @notice Holders can cash out their tokens to reclaim some of a project's surplus, or to trigger rules
|
|
1179
|
-
/// by
|
|
1180
|
-
/// the project's current ruleset's data hook.
|
|
1193
|
+
/// @notice Holders can cash out their tokens to reclaim some of a project's surplus, or to trigger rules
|
|
1194
|
+
/// determined by the project's current ruleset's data hook.
|
|
1181
1195
|
/// @dev Only a token holder or an operator with the `CASH_OUT_TOKENS` permission from that holder can cash out
|
|
1182
|
-
/// those
|
|
1183
|
-
/// tokens.
|
|
1196
|
+
/// those tokens.
|
|
1184
1197
|
/// @param holder The account cashing out tokens.
|
|
1185
1198
|
/// @param projectId The ID of the project cashing out tokens.
|
|
1186
1199
|
/// @param cashOutCount The number of project tokens to cash out, as a fixed point number with 18 decimals.
|
|
1187
1200
|
/// @param tokenToReclaim The address of the token to reclaim.
|
|
1188
1201
|
/// @param beneficiary The address to send the reclaimed terminal tokens to.
|
|
1189
|
-
/// @param metadata Bytes to send
|
|
1190
|
-
/// applicable.
|
|
1202
|
+
/// @param metadata Bytes to send to the emitted event, data hook, and cash out hook, if applicable.
|
|
1191
1203
|
/// @return reclaimAmount The number of terminal tokens reclaimed for the `beneficiary`, as a fixed point number
|
|
1192
1204
|
/// with 18 decimals.
|
|
1193
1205
|
function _cashOutTokensOf(
|
|
@@ -1475,8 +1487,8 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
1475
1487
|
/// @param metadata Bytes to send along to the emitted event and cash out hooks as applicable.
|
|
1476
1488
|
/// @param ruleset The ruleset active during this cash out as a `JBRuleset` struct.
|
|
1477
1489
|
/// @param cashOutTaxRate The cash out tax rate influencing the reclaim amount, out of
|
|
1478
|
-
/// `JBConstants.MAX_CASH_OUT_TAX_RATE`.
|
|
1479
|
-
///
|
|
1490
|
+
/// `JBConstants.MAX_CASH_OUT_TAX_RATE`.
|
|
1491
|
+
/// @param beneficiary The address which will receive any cashed out terminal tokens.
|
|
1480
1492
|
/// @param specifications The hook specifications to fulfill.
|
|
1481
1493
|
/// @return amountEligibleForFees The amount of funds which were allocated to cash out hooks and are eligible for
|
|
1482
1494
|
/// fees.
|
|
@@ -1682,8 +1694,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
1682
1694
|
/// decimals as the token's accounting context. If this terminal's token is the native token, `amount` is ignored
|
|
1683
1695
|
/// and `msg.value` is used in its place.
|
|
1684
1696
|
/// @param payer The address making the payment.
|
|
1685
|
-
/// @param beneficiary The
|
|
1686
|
-
/// applicable.
|
|
1697
|
+
/// @param beneficiary The token recipient passed to the ruleset's data hook and pay hook, if applicable.
|
|
1687
1698
|
/// @param memo A memo to pass along to the emitted event.
|
|
1688
1699
|
/// @param metadata Bytes to send along to the emitted event, as well as the data hook and pay hook if applicable.
|
|
1689
1700
|
function _pay(
|
|
@@ -2061,8 +2072,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
|
|
|
2061
2072
|
}
|
|
2062
2073
|
|
|
2063
2074
|
/// @notice Allows a project to send out funds from its surplus up to the current surplus allowance.
|
|
2064
|
-
/// @dev Only a project's owner or an operator with the `USE_ALLOWANCE` permission
|
|
2065
|
-
/// surplus allowance.
|
|
2075
|
+
/// @dev Only a project's owner or an operator with the owner's `USE_ALLOWANCE` permission can use the allowance.
|
|
2066
2076
|
/// @dev Incurs the protocol fee unless the caller is a feeless address.
|
|
2067
2077
|
/// @param projectId The ID of the project to use the surplus allowance of.
|
|
2068
2078
|
/// @param owner The project's owner.
|
package/src/JBPermissions.sol
CHANGED
|
@@ -17,17 +17,21 @@ contract JBPermissions is ERC2771Context, IJBPermissions {
|
|
|
17
17
|
// --------------------------- custom errors ------------------------- //
|
|
18
18
|
//*********************************************************************//
|
|
19
19
|
|
|
20
|
+
/// @notice Thrown when attempting to set the reserved permission ID 0.
|
|
20
21
|
error JBPermissions_NoZeroPermission(address account, address operator, uint256 projectId);
|
|
22
|
+
|
|
23
|
+
/// @notice Thrown when a permission ID is greater than the maximum of 255.
|
|
21
24
|
error JBPermissions_PermissionIdOutOfBounds(uint256 permissionId);
|
|
25
|
+
|
|
26
|
+
/// @notice Thrown when the caller is not the account and lacks ROOT permission to set permissions on its behalf.
|
|
22
27
|
error JBPermissions_Unauthorized(address account, address operator, uint256 projectId, uint256 permissionId);
|
|
23
28
|
|
|
24
29
|
//*********************************************************************//
|
|
25
30
|
// ------------------------- public constants ------------------------ //
|
|
26
31
|
//*********************************************************************//
|
|
27
32
|
|
|
28
|
-
/// @notice
|
|
29
|
-
///
|
|
30
|
-
/// the account. Setting permissions for project ID 0 is powerful and should be done carefully.
|
|
33
|
+
/// @notice Project ID 0 acts as a wildcard for permissions across all projects owned by the account.
|
|
34
|
+
/// @dev Setting permissions for project ID 0 is powerful and should be done carefully.
|
|
31
35
|
uint256 public constant override WILDCARD_PROJECT_ID = 0;
|
|
32
36
|
|
|
33
37
|
//*********************************************************************//
|
|
@@ -35,8 +39,7 @@ contract JBPermissions is ERC2771Context, IJBPermissions {
|
|
|
35
39
|
//*********************************************************************//
|
|
36
40
|
|
|
37
41
|
/// @notice The packed permission bitmap that an account has granted to an operator for a specific project.
|
|
38
|
-
/// @dev Each bit in the returned `uint256` corresponds to a permission ID (0–255). A `1` bit means
|
|
39
|
-
/// permission
|
|
42
|
+
/// @dev Each bit in the returned `uint256` corresponds to a permission ID (0–255). A `1` bit means the permission
|
|
40
43
|
/// is granted. See `JBPermissionIds` for the meaning of each ID.
|
|
41
44
|
/// @custom:param operator The address of the operator.
|
|
42
45
|
/// @custom:param account The address of the account operated on behalf of.
|
package/src/JBPrices.sol
CHANGED
|
@@ -23,10 +23,19 @@ contract JBPrices is JBControlled, JBPermissioned, ERC2771Context, Ownable, IJBP
|
|
|
23
23
|
// --------------------------- custom errors ------------------------- //
|
|
24
24
|
//*********************************************************************//
|
|
25
25
|
|
|
26
|
+
/// @notice Thrown when adding a price feed that is already registered for the same currency pair.
|
|
26
27
|
error JBPrices_PriceFeedAlreadyAdded(IJBPriceFeed feed);
|
|
28
|
+
|
|
29
|
+
/// @notice Thrown when no configured price feed can be found for the requested currency pair.
|
|
27
30
|
error JBPrices_PriceFeedNotFound(uint256 projectId, uint256 pricingCurrency, uint256 unitCurrency);
|
|
31
|
+
|
|
32
|
+
/// @notice Thrown when the provided price feed is the zero address.
|
|
28
33
|
error JBPrices_ZeroPriceFeed();
|
|
34
|
+
|
|
35
|
+
/// @notice Thrown when the pricing currency provided is zero.
|
|
29
36
|
error JBPrices_ZeroPricingCurrency(uint256 projectId, uint256 pricingCurrency);
|
|
37
|
+
|
|
38
|
+
/// @notice Thrown when the unit currency provided is zero.
|
|
30
39
|
error JBPrices_ZeroUnitCurrency(uint256 projectId, uint256 unitCurrency);
|
|
31
40
|
|
|
32
41
|
//*********************************************************************//
|
package/src/JBProjects.sol
CHANGED
|
@@ -18,8 +18,13 @@ contract JBProjects is ERC721, ERC2771Context, Ownable, IJBProjects {
|
|
|
18
18
|
// --------------------------- custom errors ------------------------- //
|
|
19
19
|
//*********************************************************************//
|
|
20
20
|
|
|
21
|
+
/// @notice Thrown when the configured creation fee exceeds the allowed maximum.
|
|
21
22
|
error JBProjects_CreationFeeExceedsMax(uint256 fee, uint256 max);
|
|
23
|
+
|
|
24
|
+
/// @notice Thrown when the native value sent does not equal the required creation fee.
|
|
22
25
|
error JBProjects_InvalidCreationFee(uint256 value, uint256 requiredFee);
|
|
26
|
+
|
|
27
|
+
/// @notice Thrown when a non-zero creation fee is configured without a fee receiver.
|
|
23
28
|
error JBProjects_ZeroCreationFeeReceiver();
|
|
24
29
|
|
|
25
30
|
//*********************************************************************//
|
package/src/JBRulesets.sol
CHANGED
|
@@ -25,11 +25,23 @@ contract JBRulesets is JBControlled, IJBRulesets {
|
|
|
25
25
|
// --------------------------- custom errors ------------------------- //
|
|
26
26
|
//*********************************************************************//
|
|
27
27
|
|
|
28
|
+
/// @notice Thrown when the approval hook is not a contract or does not support the `IJBRulesetApprovalHook`
|
|
29
|
+
/// interface.
|
|
28
30
|
error JBRulesets_InvalidRulesetApprovalHook(IJBRulesetApprovalHook hook);
|
|
31
|
+
|
|
32
|
+
/// @notice Thrown when the ruleset duration exceeds the uint32 maximum.
|
|
29
33
|
error JBRulesets_InvalidRulesetDuration(uint256 duration, uint256 limit);
|
|
34
|
+
|
|
35
|
+
/// @notice Thrown when the ruleset's start plus duration exceeds the uint48 maximum.
|
|
30
36
|
error JBRulesets_InvalidRulesetEndTime(uint256 timestamp, uint256 limit);
|
|
37
|
+
|
|
38
|
+
/// @notice Thrown when the ruleset weight exceeds the uint112 maximum.
|
|
31
39
|
error JBRulesets_InvalidWeight(uint256 weight, uint256 limit);
|
|
40
|
+
|
|
41
|
+
/// @notice Thrown when the weight cut percent exceeds 100%.
|
|
32
42
|
error JBRulesets_InvalidWeightCutPercent(uint256 percent);
|
|
43
|
+
|
|
44
|
+
/// @notice Thrown when too many weight-cut iterations remain and the weight cache must be populated first.
|
|
33
45
|
error JBRulesets_WeightCacheRequired(uint256 projectId);
|
|
34
46
|
|
|
35
47
|
//*********************************************************************//
|
|
@@ -46,8 +58,7 @@ contract JBRulesets is JBControlled, IJBRulesets {
|
|
|
46
58
|
|
|
47
59
|
/// @notice The ID of the ruleset with the latest start time for a specific project, whether the ruleset has been
|
|
48
60
|
/// approved or not.
|
|
49
|
-
/// @dev If a project has multiple rulesets queued,
|
|
50
|
-
/// "changeable" cycle.
|
|
61
|
+
/// @dev If a project has multiple rulesets queued, `latestRulesetIdOf` is the last "changeable" cycle.
|
|
51
62
|
/// @custom:param projectId The ID of the project to get the latest ruleset ID of.
|
|
52
63
|
/// @return latestRulesetIdOf The `rulesetId` of the project's latest ruleset.
|
|
53
64
|
mapping(uint256 projectId => uint256) public override latestRulesetIdOf;
|
|
@@ -206,9 +217,7 @@ contract JBRulesets is JBControlled, IJBRulesets {
|
|
|
206
217
|
|
|
207
218
|
/// @notice Cache the value of the ruleset weight for a specific ruleset.
|
|
208
219
|
/// @dev The caller should pass the ruleset ID that `currentOf()` actually uses. When a queued ruleset is rejected
|
|
209
|
-
/// by an approval hook, `currentOf()` falls back to the base ruleset
|
|
210
|
-
/// ID,
|
|
211
|
-
/// not the rejected latest.
|
|
220
|
+
/// by an approval hook, `currentOf()` falls back to the base ruleset, not the rejected latest.
|
|
212
221
|
/// @param projectId The ID of the project having its ruleset weight cached.
|
|
213
222
|
/// @param rulesetId The ID of the ruleset to update the cache for.
|
|
214
223
|
function updateRulesetWeightCache(uint256 projectId, uint256 rulesetId) external override {
|
|
@@ -396,8 +405,8 @@ contract JBRulesets is JBControlled, IJBRulesets {
|
|
|
396
405
|
// Get a reference to the approval status.
|
|
397
406
|
JBApprovalStatus approvalStatus = _approvalStatusOf({projectId: projectId, ruleset: ruleset});
|
|
398
407
|
|
|
399
|
-
// While the ruleset has
|
|
400
|
-
// the ruleset that the latest is based on, which has the latest approved configuration.
|
|
408
|
+
// While the ruleset has an approval hook that isn't approved or if it hasn't yet started, get a reference
|
|
409
|
+
// to the ruleset that the latest is based on, which has the latest approved configuration.
|
|
401
410
|
while (
|
|
402
411
|
(approvalStatus != JBApprovalStatus.Approved && approvalStatus != JBApprovalStatus.Empty)
|
|
403
412
|
// forge-lint: disable-next-line(block-timestamp)
|
|
@@ -472,7 +481,7 @@ contract JBRulesets is JBControlled, IJBRulesets {
|
|
|
472
481
|
// Keep a reference to its approval status.
|
|
473
482
|
JBApprovalStatus approvalStatus;
|
|
474
483
|
|
|
475
|
-
// If an upcoming approvable ruleset has been queued, and
|
|
484
|
+
// If an upcoming approvable ruleset has been queued, and its approval status is Approved or ApprovalExpected,
|
|
476
485
|
// return its ruleset struct
|
|
477
486
|
if (upcomingApprovableRulesetId != 0) {
|
|
478
487
|
ruleset = _getStructFor({projectId: projectId, rulesetId: upcomingApprovableRulesetId, withMetadata: true});
|
|
@@ -495,7 +504,7 @@ contract JBRulesets is JBControlled, IJBRulesets {
|
|
|
495
504
|
ruleset = _getStructFor({projectId: projectId, rulesetId: latestRulesetIdOf[projectId], withMetadata: true});
|
|
496
505
|
|
|
497
506
|
// If the latest ruleset starts in the future, it must start in the distant future
|
|
498
|
-
// Since
|
|
507
|
+
// Since it's not the upcoming approvable ruleset. In this case, base the upcoming ruleset on the base
|
|
499
508
|
// ruleset.
|
|
500
509
|
// forge-lint: disable-next-line(block-timestamp)
|
|
501
510
|
while (ruleset.start > block.timestamp) {
|
|
@@ -562,8 +571,7 @@ contract JBRulesets is JBControlled, IJBRulesets {
|
|
|
562
571
|
/// @notice The date that is the nearest multiple of the base ruleset's duration from the start of the next cycle.
|
|
563
572
|
/// @param baseRulesetStart The start time of the base ruleset.
|
|
564
573
|
/// @param baseRulesetDuration The duration of the base ruleset.
|
|
565
|
-
/// @param mustStartAtOrAfter The earliest
|
|
566
|
-
/// timestamp.
|
|
574
|
+
/// @param mustStartAtOrAfter The earliest timestamp the next ruleset can start at.
|
|
567
575
|
/// @return start The next start time.
|
|
568
576
|
function deriveStartFrom(
|
|
569
577
|
uint256 baseRulesetStart,
|
|
@@ -691,8 +699,7 @@ contract JBRulesets is JBControlled, IJBRulesets {
|
|
|
691
699
|
/// @param projectId The ID of the project to update the latest ruleset for.
|
|
692
700
|
/// @param rulesetId The timestamp of when the ruleset was queued.
|
|
693
701
|
/// @param weight The weight to store in the queued ruleset.
|
|
694
|
-
/// @param mustStartAtOrAfter The earliest
|
|
695
|
-
/// timestamp.
|
|
702
|
+
/// @param mustStartAtOrAfter The earliest timestamp the ruleset can start at.
|
|
696
703
|
function _configureIntrinsicPropertiesFor(
|
|
697
704
|
uint256 projectId,
|
|
698
705
|
uint256 rulesetId,
|
|
@@ -723,7 +730,7 @@ contract JBRulesets is JBControlled, IJBRulesets {
|
|
|
723
730
|
// Get a reference to the approval status.
|
|
724
731
|
JBApprovalStatus approvalStatus = _approvalStatusOf({projectId: projectId, ruleset: baseRuleset});
|
|
725
732
|
|
|
726
|
-
// If the base ruleset has started but wasn't approved if
|
|
733
|
+
// If the base ruleset has started but wasn't approved if an approval hook exists
|
|
727
734
|
// OR it hasn't started but is currently approved
|
|
728
735
|
// OR it hasn't started but it is likely to be approved and takes place before the proposed one,
|
|
729
736
|
// set the struct to be the ruleset it's based on, which carries the latest approved ruleset.
|
|
@@ -779,8 +786,7 @@ contract JBRulesets is JBControlled, IJBRulesets {
|
|
|
779
786
|
/// @param projectId The ID of the project to initialize the ruleset for.
|
|
780
787
|
/// @param baseRuleset The ruleset struct to base the newly initialized one on.
|
|
781
788
|
/// @param rulesetId The `rulesetId` for the ruleset to initialize.
|
|
782
|
-
/// @param mustStartAtOrAfter The earliest
|
|
783
|
-
/// timestamp.
|
|
789
|
+
/// @param mustStartAtOrAfter The earliest timestamp the ruleset can start at.
|
|
784
790
|
/// @param weight The weight to give the newly initialized ruleset.
|
|
785
791
|
function _initializeRulesetFor(
|
|
786
792
|
uint256 projectId,
|
package/src/JBSplits.sol
CHANGED
|
@@ -19,8 +19,13 @@ contract JBSplits is JBControlled, IJBSplits {
|
|
|
19
19
|
// --------------------------- custom errors ------------------------- //
|
|
20
20
|
//*********************************************************************//
|
|
21
21
|
|
|
22
|
+
/// @notice Thrown when a new set of splits omits a still-locked split from the previous set.
|
|
22
23
|
error JBSplits_PreviousLockedSplitsNotIncluded(uint256 projectId, uint256 rulesetId);
|
|
24
|
+
|
|
25
|
+
/// @notice Thrown when the splits in a group sum to more than 100%.
|
|
23
26
|
error JBSplits_TotalPercentExceeds100(uint256 projectId, uint256 rulesetId, uint256 groupId, uint256 percentTotal);
|
|
27
|
+
|
|
28
|
+
/// @notice Thrown when a split is configured with a percent of zero.
|
|
24
29
|
error JBSplits_ZeroSplitPercent(uint256 projectId, uint256 rulesetId, uint256 groupId, uint256 splitIndex);
|
|
25
30
|
|
|
26
31
|
//*********************************************************************//
|
package/src/JBTerminalStore.sol
CHANGED
|
@@ -39,22 +39,48 @@ contract JBTerminalStore is IJBTerminalStore {
|
|
|
39
39
|
// --------------------------- custom errors ------------------------- //
|
|
40
40
|
//*********************************************************************//
|
|
41
41
|
|
|
42
|
+
/// @notice Thrown when setting an accounting context for a token that already has one.
|
|
42
43
|
error JBTerminalStore_AccountingContextAlreadySet(address token);
|
|
44
|
+
|
|
45
|
+
/// @notice Thrown when a token's provided decimals do not match the decimals it reports.
|
|
43
46
|
error JBTerminalStore_AccountingContextDecimalsMismatch(
|
|
44
47
|
address token, uint256 providedDecimals, uint256 expectedDecimals
|
|
45
48
|
);
|
|
49
|
+
|
|
50
|
+
/// @notice Thrown when a token's decimals are outside the supported range.
|
|
46
51
|
error JBTerminalStore_AccountingContextDecimalsOutOfRange(address token, uint256 decimals);
|
|
52
|
+
|
|
53
|
+
/// @notice Thrown when the project's current ruleset does not allow adding accounting contexts.
|
|
47
54
|
error JBTerminalStore_AddingAccountingContextNotAllowed(uint256 projectId, uint256 rulesetId, address terminal);
|
|
55
|
+
|
|
56
|
+
/// @notice Thrown when the used surplus allowance exceeds the amount the controller granted.
|
|
48
57
|
error JBTerminalStore_InadequateControllerAllowance(uint256 amount, uint256 allowance);
|
|
49
58
|
|
|
59
|
+
/// @notice Thrown when the amount to use exceeds the terminal's recorded balance or surplus.
|
|
50
60
|
error JBTerminalStore_InadequateTerminalStoreBalance(uint256 amount, uint256 balance);
|
|
61
|
+
|
|
62
|
+
/// @notice Thrown when cashing out more tokens than the effective total supply.
|
|
51
63
|
error JBTerminalStore_InsufficientTokens(uint256 count, uint256 totalSupply);
|
|
64
|
+
|
|
65
|
+
/// @notice Thrown when a hook specification asks to forward more than the amount paid.
|
|
52
66
|
error JBTerminalStore_InvalidAmountToForwardHook(uint256 amount, uint256 paidAmount);
|
|
67
|
+
|
|
68
|
+
/// @notice Thrown when a hook specification is flagged as a no-op but carries a non-zero amount.
|
|
53
69
|
error JBTerminalStore_NoopHookSpecHasAmount(uint256 amount);
|
|
70
|
+
|
|
71
|
+
/// @notice Thrown when the project has no current ruleset.
|
|
54
72
|
error JBTerminalStore_RulesetNotFound(uint256 projectId);
|
|
73
|
+
|
|
74
|
+
/// @notice Thrown when paying a project whose current ruleset pauses payments.
|
|
55
75
|
error JBTerminalStore_RulesetPaymentPaused(uint256 projectId, uint256 rulesetId);
|
|
76
|
+
|
|
77
|
+
/// @notice Thrown when the project's current ruleset does not allow terminal migration.
|
|
56
78
|
error JBTerminalStore_TerminalMigrationNotAllowed(uint256 projectId, uint256 rulesetId);
|
|
79
|
+
|
|
80
|
+
/// @notice Thrown when a value to record exceeds the uint224 maximum.
|
|
57
81
|
error JBTerminalStore_Uint224Overflow(uint256 value);
|
|
82
|
+
|
|
83
|
+
/// @notice Thrown when an accounting context's currency is zero.
|
|
58
84
|
error JBTerminalStore_ZeroAccountingContextCurrency(address token);
|
|
59
85
|
|
|
60
86
|
//*********************************************************************//
|
|
@@ -95,8 +121,7 @@ contract JBTerminalStore is IJBTerminalStore {
|
|
|
95
121
|
/// @notice The currency-denominated amount of funds that a project has already paid out from its payout limit
|
|
96
122
|
/// during the current ruleset for each terminal, in terms of the payout limit's currency.
|
|
97
123
|
/// @dev Increases as projects pay out funds.
|
|
98
|
-
/// @dev The used payout limit is
|
|
99
|
-
/// terminal it applies to.
|
|
124
|
+
/// @dev The used payout limit is a fixed point number with the same decimals as the terminal it applies to.
|
|
100
125
|
/// @custom:param terminal The terminal the payout limit applies to.
|
|
101
126
|
/// @custom:param projectId The ID of the project to get the used payout limit of.
|
|
102
127
|
/// @custom:param token The token the payout limit applies to in the terminal.
|
|
@@ -115,8 +140,7 @@ contract JBTerminalStore is IJBTerminalStore {
|
|
|
115
140
|
/// @notice The currency-denominated amounts of funds that a project has used from its surplus allowance during the
|
|
116
141
|
/// current ruleset for each terminal, in terms of the surplus allowance's currency.
|
|
117
142
|
/// @dev Increases as projects use their allowance.
|
|
118
|
-
/// @dev The used surplus allowance is
|
|
119
|
-
/// terminal it applies to.
|
|
143
|
+
/// @dev The used surplus allowance is a fixed point number with the same decimals as the terminal it applies to.
|
|
120
144
|
/// @dev Surplus allowance usage is keyed by `ruleset.id`, not cycle number. Implicit cycle progression
|
|
121
145
|
/// (duration-based auto-cycling) does not reset allowance — this is by design. Projects must queue a new ruleset
|
|
122
146
|
/// to get a fresh allowance.
|
|
@@ -388,8 +412,7 @@ contract JBTerminalStore is IJBTerminalStore {
|
|
|
388
412
|
}
|
|
389
413
|
}
|
|
390
414
|
|
|
391
|
-
/// @notice Records a payout
|
|
392
|
-
/// terminal during `sendPayoutsOf`.
|
|
415
|
+
/// @notice Records a payout during `sendPayoutsOf`, decrementing balance and enforcing the payout limit.
|
|
393
416
|
/// @dev Reverts if the total payouts for this cycle would exceed the ruleset's payout limit. The balance is
|
|
394
417
|
/// decremented before validation (safe because the entire tx reverts atomically on failure).
|
|
395
418
|
/// @param projectId The ID of the project that is paying out funds.
|
|
@@ -465,7 +488,7 @@ contract JBTerminalStore is IJBTerminalStore {
|
|
|
465
488
|
revert JBTerminalStore_InadequateTerminalStoreBalance({amount: amountPaidOut, balance: currentBalance});
|
|
466
489
|
}
|
|
467
490
|
|
|
468
|
-
//
|
|
491
|
+
// Remove the paid out funds from the project's token balance.
|
|
469
492
|
unchecked {
|
|
470
493
|
balanceOf[msg.sender][projectId][token] = currentBalance - amountPaidOut;
|
|
471
494
|
}
|
|
@@ -786,8 +809,7 @@ contract JBTerminalStore is IJBTerminalStore {
|
|
|
786
809
|
}
|
|
787
810
|
|
|
788
811
|
/// @notice Simulates a payment without modifying state.
|
|
789
|
-
/// @dev Invokes data hooks if configured. Returns
|
|
790
|
-
/// `recordPaymentFrom` would produce.
|
|
812
|
+
/// @dev Invokes data hooks if configured. Returns what `recordPaymentFrom` would produce.
|
|
791
813
|
/// @param terminal The terminal to simulate the payment from.
|
|
792
814
|
/// @param payer The address of the payer.
|
|
793
815
|
/// @param amount The amount to pay.
|
|
@@ -1137,7 +1159,7 @@ contract JBTerminalStore is IJBTerminalStore {
|
|
|
1137
1159
|
if (weight == 0) return (ruleset, 0, hookSpecifications, balanceDiff);
|
|
1138
1160
|
|
|
1139
1161
|
// If the terminal should base its weight on a currency other than the terminal's currency, determine the
|
|
1140
|
-
// factor. The weight is always a fixed point
|
|
1162
|
+
// factor. The weight is always a fixed point number with 18 decimals. To ensure this, the ratio should use the
|
|
1141
1163
|
// same
|
|
1142
1164
|
// number of decimals as the `amount`.
|
|
1143
1165
|
uint256 weightRatio = amount.currency == ruleset.baseCurrency()
|
|
@@ -1182,8 +1204,7 @@ contract JBTerminalStore is IJBTerminalStore {
|
|
|
1182
1204
|
});
|
|
1183
1205
|
}
|
|
1184
1206
|
|
|
1185
|
-
/// @notice Gets
|
|
1186
|
-
/// pre-fetched ruleset.
|
|
1207
|
+
/// @notice Gets a project's current surplus across specified terminals and tokens using a pre-fetched ruleset.
|
|
1187
1208
|
/// @dev Use this overload when the caller already has the current ruleset to avoid a redundant
|
|
1188
1209
|
/// `RULESETS.currentOf()` call.
|
|
1189
1210
|
/// @param projectId The ID of the project to get surplus for.
|
|
@@ -1330,7 +1351,7 @@ contract JBTerminalStore is IJBTerminalStore {
|
|
|
1330
1351
|
: mulDiv({
|
|
1331
1352
|
x: surplus,
|
|
1332
1353
|
y: 10 ** _MAX_FIXED_POINT_FIDELITY, // Use `_MAX_FIXED_POINT_FIDELITY` to keep as much of the
|
|
1333
|
-
//
|
|
1354
|
+
// surplus's fidelity as possible when converting.
|
|
1334
1355
|
denominator: PRICES.pricePerUnitOf({
|
|
1335
1356
|
projectId: projectId,
|
|
1336
1357
|
pricingCurrency: accountingContext.currency,
|
package/src/JBTokens.sol
CHANGED
|
@@ -19,16 +19,37 @@ contract JBTokens is JBControlled, IJBTokens {
|
|
|
19
19
|
// --------------------------- custom errors ------------------------- //
|
|
20
20
|
//*********************************************************************//
|
|
21
21
|
|
|
22
|
+
/// @notice Thrown when deploying a token with an empty name.
|
|
22
23
|
error JBTokens_EmptyName(uint256 projectId);
|
|
24
|
+
|
|
25
|
+
/// @notice Thrown when deploying a token with an empty symbol.
|
|
23
26
|
error JBTokens_EmptySymbol(uint256 projectId);
|
|
27
|
+
|
|
28
|
+
/// @notice Thrown when the token to set is the zero address.
|
|
24
29
|
error JBTokens_EmptyToken(uint256 projectId);
|
|
30
|
+
|
|
31
|
+
/// @notice Thrown when burning more credits than the holder's credit balance.
|
|
25
32
|
error JBTokens_InsufficientCredits(uint256 count, uint256 creditBalance);
|
|
33
|
+
|
|
34
|
+
/// @notice Thrown when burning more tokens than the holder's combined token and credit balance.
|
|
26
35
|
error JBTokens_InsufficientTokensToBurn(uint256 count, uint256 tokenBalance);
|
|
36
|
+
|
|
37
|
+
/// @notice Thrown when minting would push the total supply past the uint208 maximum.
|
|
27
38
|
error JBTokens_OverflowAlert(uint256 value, uint256 limit);
|
|
39
|
+
|
|
40
|
+
/// @notice Thrown when the project already has a token set.
|
|
28
41
|
error JBTokens_ProjectAlreadyHasToken(IJBToken token);
|
|
42
|
+
|
|
43
|
+
/// @notice Thrown when the token is already in use by another project.
|
|
29
44
|
error JBTokens_TokenAlreadyBeingUsed(uint256 projectId);
|
|
45
|
+
|
|
46
|
+
/// @notice Thrown when the token reports that it cannot be added to the project.
|
|
30
47
|
error JBTokens_TokenCantBeAdded(uint256 projectId);
|
|
48
|
+
|
|
49
|
+
/// @notice Thrown when the project has no token set.
|
|
31
50
|
error JBTokens_TokenNotFound(uint256 projectId);
|
|
51
|
+
|
|
52
|
+
/// @notice Thrown when the token does not use 18 decimals.
|
|
32
53
|
error JBTokens_TokensMustHave18Decimals(uint256 decimals);
|
|
33
54
|
|
|
34
55
|
//*********************************************************************//
|
|
@@ -12,6 +12,7 @@ abstract contract JBControlled is IJBControlled {
|
|
|
12
12
|
// --------------------------- custom errors -------------------------- //
|
|
13
13
|
//*********************************************************************//
|
|
14
14
|
|
|
15
|
+
/// @notice Thrown when the caller is not the controller of the specified project.
|
|
15
16
|
error JBControlled_ControllerUnauthorized(address controller);
|
|
16
17
|
|
|
17
18
|
//*********************************************************************//
|
|
@@ -14,6 +14,7 @@ abstract contract JBPermissioned is Context, IJBPermissioned {
|
|
|
14
14
|
// --------------------------- custom errors -------------------------- //
|
|
15
15
|
//*********************************************************************//
|
|
16
16
|
|
|
17
|
+
/// @notice Thrown when the sender lacks the required permission from the account to perform the operation.
|
|
17
18
|
error JBPermissioned_Unauthorized(address account, address sender, uint256 projectId, uint256 permissionId);
|
|
18
19
|
|
|
19
20
|
//*********************************************************************//
|
|
@@ -84,9 +85,7 @@ abstract contract JBPermissioned is Context, IJBPermissioned {
|
|
|
84
85
|
) revert JBPermissioned_Unauthorized(account, sender, projectId, permissionId);
|
|
85
86
|
}
|
|
86
87
|
|
|
87
|
-
/// @notice If
|
|
88
|
-
/// account or
|
|
89
|
-
/// have the relevant permission.
|
|
88
|
+
/// @notice If `alsoGrantAccessIf` is false, require the message sender to be the account or have permission.
|
|
90
89
|
/// @param account The account to allow.
|
|
91
90
|
/// @param projectId The project ID to check the permission under.
|
|
92
91
|
/// @param permissionId The required permission ID. The operator must have this permission within the specified
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
pragma solidity ^0.8.0;
|
|
3
3
|
|
|
4
4
|
/// @notice The lifecycle states a queued ruleset can be in relative to its approval hook.
|
|
5
|
-
/// @dev `Empty` — no ruleset exists.
|
|
6
|
-
///
|
|
7
|
-
///
|
|
8
|
-
/// `
|
|
9
|
-
///
|
|
10
|
-
/// ruleset continues.
|
|
5
|
+
/// @dev `Empty` — no ruleset exists.
|
|
6
|
+
/// `Upcoming` — queued but not yet eligible for approval check.
|
|
7
|
+
/// `Active` — currently governing the project.
|
|
8
|
+
/// `ApprovalExpected` — the deadline hasn't passed yet, expected to be approved.
|
|
9
|
+
/// `Approved` — passed the approval hook and will take effect.
|
|
10
|
+
/// `Failed` — rejected by the approval hook; the previous ruleset continues.
|
|
11
11
|
enum JBApprovalStatus {
|
|
12
12
|
Empty,
|
|
13
13
|
Upcoming,
|
|
@@ -75,8 +75,7 @@ interface IJBCashOutTerminal is IJBTerminal {
|
|
|
75
75
|
JBCashOutHookSpecification[] memory hookSpecifications
|
|
76
76
|
);
|
|
77
77
|
|
|
78
|
-
/// @notice Burn a holder's project tokens to reclaim a proportional share of
|
|
79
|
-
/// terminal token).
|
|
78
|
+
/// @notice Burn a holder's project tokens to reclaim a proportional share of surplus in a terminal token.
|
|
80
79
|
/// @param holder The address whose project tokens are being burned.
|
|
81
80
|
/// @param projectId The ID of the project whose project tokens are being burned.
|
|
82
81
|
/// @param cashOutCount The number of project tokens to burn.
|