@bananapus/core-v6 0.0.42 → 0.0.43

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.
@@ -40,8 +40,10 @@ contract JBTerminalStore is IJBTerminalStore {
40
40
  //*********************************************************************//
41
41
 
42
42
  error JBTerminalStore_AccountingContextAlreadySet(address token);
43
- error JBTerminalStore_AccountingContextDecimalsMismatch();
44
- error JBTerminalStore_AddingAccountingContextNotAllowed();
43
+ error JBTerminalStore_AccountingContextDecimalsMismatch(
44
+ address token, uint256 providedDecimals, uint256 expectedDecimals
45
+ );
46
+ error JBTerminalStore_AddingAccountingContextNotAllowed(uint256 projectId, uint256 rulesetId, address terminal);
45
47
  error JBTerminalStore_InadequateControllerAllowance(uint256 amount, uint256 allowance);
46
48
  error JBTerminalStore_InadequateControllerPayoutLimit(uint256 amount, uint256 limit);
47
49
  error JBTerminalStore_InadequateTerminalStoreBalance(uint256 amount, uint256 balance);
@@ -49,10 +51,10 @@ contract JBTerminalStore is IJBTerminalStore {
49
51
  error JBTerminalStore_InvalidAmountToForwardHook(uint256 amount, uint256 paidAmount);
50
52
  error JBTerminalStore_NoopHookSpecHasAmount(uint256 amount);
51
53
  error JBTerminalStore_RulesetNotFound(uint256 projectId);
52
- error JBTerminalStore_RulesetPaymentPaused();
53
- error JBTerminalStore_TerminalMigrationNotAllowed();
54
+ error JBTerminalStore_RulesetPaymentPaused(uint256 projectId, uint256 rulesetId);
55
+ error JBTerminalStore_TerminalMigrationNotAllowed(uint256 projectId, uint256 rulesetId);
54
56
  error JBTerminalStore_Uint224Overflow(uint256 value);
55
- error JBTerminalStore_ZeroAccountingContextCurrency();
57
+ error JBTerminalStore_ZeroAccountingContextCurrency(address token);
56
58
 
57
59
  //*********************************************************************//
58
60
  // -------------------------- internal constants --------------------- //
@@ -176,7 +178,9 @@ contract JBTerminalStore is IJBTerminalStore {
176
178
 
177
179
  // Make sure that if there's a ruleset, it allows adding accounting contexts.
178
180
  if (ruleset.id != 0 && !ruleset.allowAddAccountingContext()) {
179
- revert JBTerminalStore_AddingAccountingContextNotAllowed();
181
+ revert JBTerminalStore_AddingAccountingContextNotAllowed({
182
+ projectId: projectId, rulesetId: ruleset.id, terminal: msg.sender
183
+ });
180
184
  }
181
185
 
182
186
  // Record each accounting context.
@@ -185,20 +189,22 @@ contract JBTerminalStore is IJBTerminalStore {
185
189
 
186
190
  // Make sure the token accounting context isn't already set.
187
191
  if (_accountingContextForTokenOf[msg.sender][projectId][context.token].token != address(0)) {
188
- revert JBTerminalStore_AccountingContextAlreadySet(context.token);
192
+ revert JBTerminalStore_AccountingContextAlreadySet({token: context.token});
189
193
  }
190
194
 
191
195
  // Keep track of a flag indicating if we know the provided decimals are incorrect.
192
196
  bool knownInvalidDecimals;
197
+ uint256 expectedDecimals;
193
198
 
194
199
  // Check if the token is the native token and has the correct decimals.
195
200
  if (context.token == JBConstants.NATIVE_TOKEN && context.decimals != 18) {
196
201
  knownInvalidDecimals = true;
202
+ expectedDecimals = 18;
197
203
  } else if (context.token != JBConstants.NATIVE_TOKEN && context.token.code.length > 0) {
198
- // slither-disable-next-line calls-loop
199
204
  try IERC20Metadata(context.token).decimals() returns (uint8 decimals) {
200
205
  if (context.decimals != decimals) {
201
206
  knownInvalidDecimals = true;
207
+ expectedDecimals = decimals;
202
208
  }
203
209
  } catch {
204
210
  // The token didn't support `decimals`.
@@ -210,11 +216,13 @@ contract JBTerminalStore is IJBTerminalStore {
210
216
 
211
217
  // Make sure the decimals are correct.
212
218
  if (knownInvalidDecimals) {
213
- revert JBTerminalStore_AccountingContextDecimalsMismatch();
219
+ revert JBTerminalStore_AccountingContextDecimalsMismatch({
220
+ token: context.token, providedDecimals: context.decimals, expectedDecimals: expectedDecimals
221
+ });
214
222
  }
215
223
 
216
224
  // Make sure the currency is non-zero.
217
- if (context.currency == 0) revert JBTerminalStore_ZeroAccountingContextCurrency();
225
+ if (context.currency == 0) revert JBTerminalStore_ZeroAccountingContextCurrency({token: context.token});
218
226
 
219
227
  // Store the accounting context.
220
228
  _accountingContextForTokenOf[msg.sender][projectId][context.token] = context;
@@ -303,7 +311,7 @@ contract JBTerminalStore is IJBTerminalStore {
303
311
 
304
312
  // The amount being reclaimed must be within the project's balance.
305
313
  if (balanceDiff > currentBalance) {
306
- revert JBTerminalStore_InadequateTerminalStoreBalance(balanceDiff, currentBalance);
314
+ revert JBTerminalStore_InadequateTerminalStoreBalance({amount: balanceDiff, balance: currentBalance});
307
315
  }
308
316
 
309
317
  // Remove the reclaimed funds from the project's balance.
@@ -404,7 +412,7 @@ contract JBTerminalStore is IJBTerminalStore {
404
412
 
405
413
  // The amount being paid out must be available.
406
414
  if (amountPaidOut > currentBalance) {
407
- revert JBTerminalStore_InadequateTerminalStoreBalance(amountPaidOut, currentBalance);
415
+ revert JBTerminalStore_InadequateTerminalStoreBalance({amount: amountPaidOut, balance: currentBalance});
408
416
  }
409
417
 
410
418
  // The new total amount which has been paid out during this ruleset.
@@ -420,7 +428,7 @@ contract JBTerminalStore is IJBTerminalStore {
420
428
 
421
429
  // Make sure the new used amount is within the payout limit.
422
430
  if (newUsedPayoutLimitOf > payoutLimit || payoutLimit == 0) {
423
- revert JBTerminalStore_InadequateControllerPayoutLimit(newUsedPayoutLimitOf, payoutLimit);
431
+ revert JBTerminalStore_InadequateControllerPayoutLimit({amount: newUsedPayoutLimitOf, limit: payoutLimit});
424
432
  }
425
433
 
426
434
  // Removed the paid out funds from the project's token balance.
@@ -444,7 +452,7 @@ contract JBTerminalStore is IJBTerminalStore {
444
452
 
445
453
  // Terminal migration must be allowed.
446
454
  if (!ruleset.allowTerminalMigration()) {
447
- revert JBTerminalStore_TerminalMigrationNotAllowed();
455
+ revert JBTerminalStore_TerminalMigrationNotAllowed({projectId: projectId, rulesetId: ruleset.id});
448
456
  }
449
457
 
450
458
  // Return the current balance, which is the amount being migrated.
@@ -525,7 +533,9 @@ contract JBTerminalStore is IJBTerminalStore {
525
533
 
526
534
  // Make sure the new used amount is within the allowance.
527
535
  if (newUsedSurplusAllowanceOf > surplusAllowance || surplusAllowance == 0) {
528
- revert JBTerminalStore_InadequateControllerAllowance(newUsedSurplusAllowanceOf, surplusAllowance);
536
+ revert JBTerminalStore_InadequateControllerAllowance({
537
+ amount: newUsedSurplusAllowanceOf, allowance: surplusAllowance
538
+ });
529
539
  }
530
540
 
531
541
  // Cache the balance slot to avoid redundant storage reads.
@@ -915,7 +925,7 @@ contract JBTerminalStore is IJBTerminalStore {
915
925
  // Noop specifications are informational only, so they can't also request forwarded funds.
916
926
  for (uint256 i; i < hookSpecifications.length;) {
917
927
  if (hookSpecifications[i].noop && hookSpecifications[i].amount != 0) {
918
- revert JBTerminalStore_NoopHookSpecHasAmount(hookSpecifications[i].amount);
928
+ revert JBTerminalStore_NoopHookSpecHasAmount({amount: hookSpecifications[i].amount});
919
929
  }
920
930
  unchecked {
921
931
  ++i;
@@ -983,7 +993,7 @@ contract JBTerminalStore is IJBTerminalStore {
983
993
 
984
994
  // Can't cash out more tokens than are in the supply.
985
995
  if (cashOutCount > effectiveTotalSupply) {
986
- revert JBTerminalStore_InsufficientTokens(cashOutCount, effectiveTotalSupply);
996
+ revert JBTerminalStore_InsufficientTokens({count: cashOutCount, totalSupply: effectiveTotalSupply});
987
997
  }
988
998
 
989
999
  // SECURITY NOTE: The data hook has absolute control over cash-out pricing.
@@ -991,7 +1001,7 @@ contract JBTerminalStore is IJBTerminalStore {
991
1001
  // completely overriding the terminal's bonding curve math. For example, setting
992
1002
  // effectiveTotalSupply = surplus makes reclaimAmount = effectiveCashOutCount, bypassing the curve.
993
1003
  // The terminal still burns the caller-supplied cashOutCount after pricing completes.
994
- // Project owners MUST audit their data hooks with the same rigor as the terminal.
1004
+ // Project owners must review their data hooks with the same rigor as the terminal.
995
1005
 
996
1006
  // If the ruleset has a data hook which is enabled for cash outs, use it to derive a claim amount and memo.
997
1007
  if (ruleset.useDataHookForCashOut() && ruleset.dataHook() != address(0)) {
@@ -1067,7 +1077,9 @@ contract JBTerminalStore is IJBTerminalStore {
1067
1077
  if (ruleset.cycleNumber == 0) revert JBTerminalStore_RulesetNotFound(projectId);
1068
1078
 
1069
1079
  // The ruleset must not have payments paused.
1070
- if (ruleset.pausePay()) revert JBTerminalStore_RulesetPaymentPaused();
1080
+ if (ruleset.pausePay()) {
1081
+ revert JBTerminalStore_RulesetPaymentPaused({projectId: projectId, rulesetId: ruleset.id});
1082
+ }
1071
1083
 
1072
1084
  // The weight according to which new tokens are to be minted, as a fixed point number with 18 decimals.
1073
1085
  uint256 weight;
@@ -1075,7 +1087,7 @@ contract JBTerminalStore is IJBTerminalStore {
1075
1087
  // SECURITY NOTE: The data hook has absolute control over payment token minting.
1076
1088
  // It can return an arbitrary weight (overriding the ruleset's weight) and hook specifications
1077
1089
  // that divert payment funds to external hooks before they reach the project's balance.
1078
- // Project owners MUST audit their data hooks with the same rigor as the terminal.
1090
+ // Project owners must review their data hooks with the same rigor as the terminal.
1079
1091
 
1080
1092
  // If the ruleset has a data hook enabled for payments, use it to derive a weight and memo.
1081
1093
  if (ruleset.useDataHookForPay() && ruleset.dataHook() != address(0)) {
@@ -1105,7 +1117,7 @@ contract JBTerminalStore is IJBTerminalStore {
1105
1117
  // Ensure that the specifications have valid amounts.
1106
1118
  for (uint256 i; i < hookSpecifications.length;) {
1107
1119
  if (hookSpecifications[i].noop && hookSpecifications[i].amount != 0) {
1108
- revert JBTerminalStore_NoopHookSpecHasAmount(hookSpecifications[i].amount);
1120
+ revert JBTerminalStore_NoopHookSpecHasAmount({amount: hookSpecifications[i].amount});
1109
1121
  }
1110
1122
 
1111
1123
  uint256 specifiedAmount = hookSpecifications[i].amount;
@@ -1113,7 +1125,9 @@ contract JBTerminalStore is IJBTerminalStore {
1113
1125
  // Can't send more to hook than was paid.
1114
1126
  if (specifiedAmount != 0) {
1115
1127
  if (specifiedAmount > balanceDiff) {
1116
- revert JBTerminalStore_InvalidAmountToForwardHook(specifiedAmount, balanceDiff);
1128
+ revert JBTerminalStore_InvalidAmountToForwardHook({
1129
+ amount: specifiedAmount, paidAmount: balanceDiff
1130
+ });
1117
1131
  }
1118
1132
 
1119
1133
  // Decrement the total amount being added to the local balance.
@@ -1319,7 +1333,6 @@ contract JBTerminalStore is IJBTerminalStore {
1319
1333
  });
1320
1334
 
1321
1335
  // Add up all the balances.
1322
- // slither-disable-next-line calls-loop
1323
1336
  surplus = (surplus == 0 || accountingContext.currency == targetCurrency)
1324
1337
  ? surplus
1325
1338
  : mulDiv({
@@ -1335,7 +1348,6 @@ contract JBTerminalStore is IJBTerminalStore {
1335
1348
  });
1336
1349
 
1337
1350
  // Get a reference to the payout limit during the ruleset for the token.
1338
- // slither-disable-next-line calls-loop
1339
1351
  JBCurrencyAmount[] memory payoutLimits = IJBController(address(DIRECTORY.controllerOf(projectId)))
1340
1352
  .FUND_ACCESS_LIMITS()
1341
1353
  .payoutLimitsOf({
@@ -1375,7 +1387,6 @@ contract JBTerminalStore is IJBTerminalStore {
1375
1387
 
1376
1388
  // Convert the `payoutLimit`'s amount to be in terms of the provided currency.
1377
1389
  if (payoutLimit.amount != 0 && payoutLimit.currency != targetCurrency) {
1378
- // slither-disable-next-line calls-loop
1379
1390
  uint256 converted = mulDiv({
1380
1391
  x: payoutLimit.amount,
1381
1392
  y: 10 ** _MAX_FIXED_POINT_FIDELITY, // Use `_MAX_FIXED_POINT_FIDELITY` to keep as much of the
package/src/JBTokens.sol CHANGED
@@ -19,8 +19,8 @@ contract JBTokens is JBControlled, IJBTokens {
19
19
  // --------------------------- custom errors ------------------------- //
20
20
  //*********************************************************************//
21
21
 
22
- error JBTokens_EmptyName();
23
- error JBTokens_EmptySymbol();
22
+ error JBTokens_EmptyName(uint256 projectId);
23
+ error JBTokens_EmptySymbol(uint256 projectId);
24
24
  error JBTokens_EmptyToken(uint256 projectId);
25
25
  error JBTokens_InsufficientCredits(uint256 count, uint256 creditBalance);
26
26
  error JBTokens_InsufficientTokensToBurn(uint256 count, uint256 tokenBalance);
@@ -28,7 +28,7 @@ contract JBTokens is JBControlled, IJBTokens {
28
28
  error JBTokens_ProjectAlreadyHasToken(IJBToken token);
29
29
  error JBTokens_TokenAlreadyBeingUsed(uint256 projectId);
30
30
  error JBTokens_TokenCantBeAdded(uint256 projectId);
31
- error JBTokens_TokenNotFound();
31
+ error JBTokens_TokenNotFound(uint256 projectId);
32
32
  error JBTokens_TokensMustHave18Decimals(uint256 decimals);
33
33
 
34
34
  //*********************************************************************//
@@ -49,7 +49,6 @@ contract JBTokens is JBControlled, IJBTokens {
49
49
 
50
50
  /// @notice The project ID that a given ERC-20 token is associated with.
51
51
  /// @custom:param token The address of the token associated with the project.
52
- // slither-disable-next-line unused-return
53
52
  mapping(IJBToken token => uint256) public override projectIdOf;
54
53
 
55
54
  /// @notice Each project's attached token contract.
@@ -92,7 +91,7 @@ contract JBTokens is JBControlled, IJBTokens {
92
91
 
93
92
  // There must be enough tokens to burn across the holder's combined token and credit balance.
94
93
  if (count > tokenBalance + creditBalance) {
95
- revert JBTokens_InsufficientTokensToBurn(count, tokenBalance + creditBalance);
94
+ revert JBTokens_InsufficientTokensToBurn({count: count, tokenBalance: tokenBalance + creditBalance});
96
95
  }
97
96
 
98
97
  // The amount of tokens to burn.
@@ -153,7 +152,7 @@ contract JBTokens is JBControlled, IJBTokens {
153
152
  IJBToken token = tokenOf[projectId];
154
153
 
155
154
  // The project must have a token contract attached.
156
- if (token == IJBToken(address(0))) revert JBTokens_TokenNotFound();
155
+ if (token == IJBToken(address(0))) revert JBTokens_TokenNotFound({projectId: projectId});
157
156
 
158
157
  // Get a reference to the amount of credits the holder has.
159
158
  uint256 creditBalance = creditBalanceOf[holder][projectId];
@@ -204,10 +203,10 @@ contract JBTokens is JBControlled, IJBTokens {
204
203
  returns (IJBToken token)
205
204
  {
206
205
  // There must be a name.
207
- if (bytes(name).length == 0) revert JBTokens_EmptyName();
206
+ if (bytes(name).length == 0) revert JBTokens_EmptyName({projectId: projectId});
208
207
 
209
208
  // There must be a symbol.
210
- if (bytes(symbol).length == 0) revert JBTokens_EmptySymbol();
209
+ if (bytes(symbol).length == 0) revert JBTokens_EmptySymbol({projectId: projectId});
211
210
 
212
211
  // The project shouldn't already have a token.
213
212
  if (tokenOf[projectId] != IJBToken(address(0))) revert JBTokens_ProjectAlreadyHasToken(tokenOf[projectId]);
@@ -263,12 +262,11 @@ contract JBTokens is JBControlled, IJBTokens {
263
262
 
264
263
  // The total supply after minting can't exceed the maximum value storable in a uint208.
265
264
  if (supply + count > type(uint208).max) {
266
- revert JBTokens_OverflowAlert(supply + count, type(uint208).max);
265
+ revert JBTokens_OverflowAlert({value: supply + count, limit: type(uint208).max});
267
266
  }
268
267
 
269
268
  if (tokensWereClaimed) {
270
269
  // If tokens should be claimed, mint tokens into the holder's wallet.
271
- // slither-disable-next-line reentrancy-events
272
270
  token.mint({account: holder, amount: count});
273
271
  } else {
274
272
  // Otherwise, add the tokens to their credits and the credit supply.
@@ -333,13 +331,13 @@ contract JBTokens is JBControlled, IJBTokens {
333
331
  IJBToken token = tokenOf[projectId];
334
332
 
335
333
  // The project must have a token contract attached.
336
- if (token == IJBToken(address(0))) revert JBTokens_TokenNotFound();
334
+ if (token == IJBToken(address(0))) revert JBTokens_TokenNotFound({projectId: projectId});
337
335
 
338
336
  // There must be a name.
339
- if (bytes(name).length == 0) revert JBTokens_EmptyName();
337
+ if (bytes(name).length == 0) revert JBTokens_EmptyName({projectId: projectId});
340
338
 
341
339
  // There must be a symbol.
342
- if (bytes(symbol).length == 0) revert JBTokens_EmptySymbol();
340
+ if (bytes(symbol).length == 0) revert JBTokens_EmptySymbol({projectId: projectId});
343
341
 
344
342
  emit SetTokenMetadata({projectId: projectId, name: name, symbol: symbol, caller: msg.sender});
345
343
 
@@ -48,10 +48,9 @@ abstract contract JBControlled is IJBControlled {
48
48
  /// @notice Only allows the controller of the specified project to proceed.
49
49
  function _onlyControllerOf(uint256 projectId) internal view {
50
50
  // Cache the controller address to avoid a redundant external call on revert.
51
- // slither-disable-next-line calls-loop
52
51
  address controller = address(DIRECTORY.controllerOf(projectId));
53
52
  if (controller != msg.sender) {
54
- revert JBControlled_ControllerUnauthorized(controller);
53
+ revert JBControlled_ControllerUnauthorized({controller: controller});
55
54
  }
56
55
  }
57
56
  }
@@ -81,12 +81,6 @@ interface IJBController is IERC165, IJBProjectUriRegistry, IJBDirectoryAccessCon
81
81
  address caller
82
82
  );
83
83
 
84
- /// @notice A project was prepared for migration from another controller.
85
- /// @param projectId The ID of the project to prepare for migration.
86
- /// @param from The controller to migrate from.
87
- /// @param caller The address that called the prep migration function.
88
- event PrepMigration(uint256 indexed projectId, address from, address caller);
89
-
90
84
  /// @notice Rulesets were queued for a project.
91
85
  /// @param rulesetId The ID of the first queued ruleset.
92
86
  /// @param projectId The ID of the project.
@@ -13,7 +13,7 @@ import {JBConstants} from "./JBConstants.sol";
13
13
  /// reclaim amount.
14
14
  library JBCashOuts {
15
15
  /// @notice Thrown when the desired output cannot be achieved (e.g., cash out tax rate is 100%).
16
- error JBCashOuts_DesiredOutputNotAchievable();
16
+ error JBCashOuts_DesiredOutputNotAchievable(uint256 desiredOutput, uint256 cashOutTaxRate, uint256 maxTaxRate);
17
17
 
18
18
  /// @notice Returns the amount of surplus terminal tokens which can be reclaimed based on the total surplus, the
19
19
  /// number of tokens to cash out, the total token supply, and the ruleset's cash out tax rate.
@@ -81,7 +81,11 @@ library JBCashOuts {
81
81
 
82
82
  // If the cash out tax rate is at maximum, no output is achievable.
83
83
  if (cashOutTaxRate == JBConstants.MAX_CASH_OUT_TAX_RATE) {
84
- revert JBCashOuts_DesiredOutputNotAchievable();
84
+ revert JBCashOuts_DesiredOutputNotAchievable({
85
+ desiredOutput: desiredOutput,
86
+ cashOutTaxRate: cashOutTaxRate,
87
+ maxTaxRate: JBConstants.MAX_CASH_OUT_TAX_RATE
88
+ });
85
89
  }
86
90
 
87
91
  // If the desired output meets or exceeds the surplus, the entire supply must be cashed out.
@@ -4,6 +4,9 @@ pragma solidity 0.8.28;
4
4
  /// @notice Well-known currency IDs used as the `baseCurrency` in ruleset metadata. These are distinct from accounting
5
5
  /// context currencies (which use `uint32(uint160(tokenAddress))`). Only used for price feed lookups in `JBPrices`.
6
6
  library JBCurrencyIds {
7
+ /// @notice The currency ID used for ETH-denominated price feeds.
7
8
  uint32 public constant ETH = 1;
9
+
10
+ /// @notice The currency ID used for USD-denominated price feeds.
8
11
  uint32 public constant USD = 2;
9
12
  }
@@ -25,10 +25,10 @@ pragma solidity 0.8.28;
25
25
  * +-----------------------+
26
26
  */
27
27
  library JBMetadataResolver {
28
- error JBMetadataResolver_DataNotPadded();
29
- error JBMetadataResolver_LengthMismatch();
30
- error JBMetadataResolver_MetadataTooLong();
31
- error JBMetadataResolver_MetadataTooShort();
28
+ error JBMetadataResolver_DataNotPadded(uint256 dataLength);
29
+ error JBMetadataResolver_LengthMismatch(uint256 idsLength, uint256 datasLength);
30
+ error JBMetadataResolver_MetadataTooLong(uint256 offset, uint256 maxOffset);
31
+ error JBMetadataResolver_MetadataTooShort(uint256 metadataLength, uint256 minMetadataLength);
32
32
 
33
33
  // The various sizes used in bytes.
34
34
  uint256 constant ID_SIZE = 4;
@@ -61,7 +61,7 @@ library JBMetadataResolver {
61
61
  returns (bytes memory newMetadata)
62
62
  {
63
63
  // Validate data padding upfront so that the fast path below cannot bypass the check.
64
- if (dataToAdd.length < 32) revert JBMetadataResolver_DataNotPadded();
64
+ if (dataToAdd.length < 32) revert JBMetadataResolver_DataNotPadded({dataLength: dataToAdd.length});
65
65
 
66
66
  // Empty original metadata and maybe something in the first 32 bytes: create new metadata
67
67
  if (originalMetadata.length <= RESERVED_SIZE) {
@@ -70,7 +70,11 @@ library JBMetadataResolver {
70
70
  }
71
71
 
72
72
  // There is something in the table offset, but not a valid entry - avoid overwriting
73
- if (originalMetadata.length < RESERVED_SIZE + ID_SIZE + 1) revert JBMetadataResolver_MetadataTooShort();
73
+ if (originalMetadata.length < RESERVED_SIZE + ID_SIZE + 1) {
74
+ revert JBMetadataResolver_MetadataTooShort({
75
+ metadataLength: originalMetadata.length, minMetadataLength: RESERVED_SIZE + ID_SIZE + 1
76
+ });
77
+ }
74
78
 
75
79
  // Get the first data offset - upcast to avoid overflow (same for other offset)...
76
80
  uint256 firstOffset = uint8(originalMetadata[RESERVED_SIZE + ID_SIZE]);
@@ -104,7 +108,9 @@ library JBMetadataResolver {
104
108
  // Increment every offset by 1 (as the table now takes one more word)
105
109
  for (uint256 j = RESERVED_SIZE + ID_SIZE; j < lastOffsetIndex + 1; j += TOTAL_ID_SIZE) {
106
110
  uint256 incremented = uint256(uint8(originalMetadata[j])) + 1;
107
- if (incremented > 255) revert JBMetadataResolver_MetadataTooLong();
111
+ if (incremented > 255) {
112
+ revert JBMetadataResolver_MetadataTooLong({offset: incremented, maxOffset: 255});
113
+ }
108
114
  // forge-lint: disable-next-line(unsafe-typecast)
109
115
  newMetadata[j] = bytes1(uint8(incremented));
110
116
  }
@@ -121,7 +127,7 @@ library JBMetadataResolver {
121
127
  // taken by the last data
122
128
  // Compute in uint256 first — casting directly to uint8 silently wraps offsets > 255.
123
129
  uint256 newOffset = lastOffset + numberOfWordslastData;
124
- if (newOffset > 255) revert JBMetadataResolver_MetadataTooLong();
130
+ if (newOffset > 255) revert JBMetadataResolver_MetadataTooLong({offset: newOffset, maxOffset: 255});
125
131
  // forge-lint: disable-next-line(unsafe-typecast)
126
132
  newMetadata = abi.encodePacked(newMetadata, idToAdd, bytes1(uint8(newOffset)));
127
133
 
@@ -167,7 +173,9 @@ library JBMetadataResolver {
167
173
  /// @param datas The list of corresponding datas
168
174
  /// @return metadata The resulting metadata
169
175
  function createMetadata(bytes4[] memory ids, bytes[] memory datas) internal pure returns (bytes memory metadata) {
170
- if (ids.length != datas.length) revert JBMetadataResolver_LengthMismatch();
176
+ if (ids.length != datas.length) {
177
+ revert JBMetadataResolver_LengthMismatch({idsLength: ids.length, datasLength: datas.length});
178
+ }
171
179
 
172
180
  // Return empty bytes for empty input arrays to avoid underflow in offset calculation below.
173
181
  if (ids.length == 0) return bytes("");
@@ -191,7 +199,7 @@ library JBMetadataResolver {
191
199
  bytes memory data = datas[i];
192
200
 
193
201
  if (data.length < 32 || data.length % JBMetadataResolver.WORD_SIZE != 0) {
194
- revert JBMetadataResolver_DataNotPadded();
202
+ revert JBMetadataResolver_DataNotPadded({dataLength: data.length});
195
203
  }
196
204
 
197
205
  // forge-lint: disable-next-line(unsafe-typecast)
@@ -199,7 +207,7 @@ library JBMetadataResolver {
199
207
  offset += data.length / JBMetadataResolver.WORD_SIZE;
200
208
 
201
209
  // Overflowing a bytes1?
202
- if (offset > 255) revert JBMetadataResolver_MetadataTooLong();
210
+ if (offset > 255) revert JBMetadataResolver_MetadataTooLong({offset: offset, maxOffset: 255});
203
211
  }
204
212
 
205
213
  // Pad the table to a multiple of 32B
@@ -277,7 +285,7 @@ library JBMetadataResolver {
277
285
  /// @param purpose A string describing the purpose associated with the id
278
286
  /// @return id The resulting ID.
279
287
  function getId(string memory purpose) internal view returns (bytes4) {
280
- return getId(purpose, address(this));
288
+ return getId({purpose: purpose, target: address(this)});
281
289
  }
282
290
 
283
291
  /// @notice Returns an unique id following a suggested format (`xor(address(this), purpose name)` where purpose name
@@ -12,6 +12,13 @@ import {JBConstants} from "./JBConstants.sol";
12
12
  /// @dev Kept local to this file because `executePayout(...)` is an implementation detail, not a shared public
13
13
  /// interface.
14
14
  interface IJBPayoutSplitGroupExecutor {
15
+ /// @notice Executes one payout split from the terminal that is using this library.
16
+ /// @param split The split to pay.
17
+ /// @param projectId The ID of the project paying the split.
18
+ /// @param token The token being paid out.
19
+ /// @param amount The amount assigned to the split.
20
+ /// @param originalMessageSender The account that started the payout flow.
21
+ /// @return netPayoutAmount The amount that was actually paid after fees or hook behavior.
15
22
  function executePayout(
16
23
  JBSplit calldata split,
17
24
  uint256 projectId,
@@ -30,6 +37,7 @@ interface IJBPayoutSplitGroupExecutor {
30
37
  /// are emitted from the terminal's address.
31
38
  library JBPayoutSplitGroupLib {
32
39
  event PayoutReverted(uint256 indexed projectId, JBSplit split, uint256 amount, bytes reason, address caller);
40
+
33
41
  event SendPayoutToSplit(
34
42
  uint256 indexed projectId,
35
43
  uint256 indexed rulesetId,
@@ -80,7 +88,6 @@ library JBPayoutSplitGroupLib {
80
88
  uint256 payoutAmount = mulDiv(leftoverAmount, split.percent, leftoverPercentage);
81
89
 
82
90
  // The final payout amount after taking out any fees.
83
- // slither-disable-next-line calls-loop
84
91
  uint256 netPayoutAmount = _sendPayoutToSplit({
85
92
  store: store, split: split, projectId: projectId, token: token, amount: payoutAmount, caller: caller
86
93
  });
@@ -140,7 +147,6 @@ library JBPayoutSplitGroupLib {
140
147
  // split from DoS-ing the entire payout. Failed splits' amounts are returned to the project balance via
141
148
  // `recordAddedBalanceFor`. Payout limit consumption is correct because the project authorized the
142
149
  // distribution.
143
- // slither-disable-next-line reentrancy-events,calls-loop
144
150
  try IJBPayoutSplitGroupExecutor(address(this))
145
151
  .executePayout({
146
152
  split: split, projectId: projectId, token: token, amount: amount, originalMessageSender: caller
@@ -154,7 +160,6 @@ library JBPayoutSplitGroupLib {
154
160
  });
155
161
 
156
162
  // Add balance back to the project.
157
- // slither-disable-next-line calls-loop
158
163
  store.recordAddedBalanceFor({projectId: projectId, token: token, amount: amount});
159
164
 
160
165
  // Since the payout failed the netPayoutAmount is zero.
@@ -4,5 +4,6 @@ pragma solidity 0.8.28;
4
4
  /// @notice Well-known split group IDs. The reserved tokens group (ID 1) defines how a project's reserved tokens are
5
5
  /// distributed. Payout split groups use the token address cast to `uint256(uint160(token))` as their group ID.
6
6
  library JBSplitGroupIds {
7
+ /// @notice The split group ID used for reserved token distributions.
7
8
  uint256 public constant RESERVED_TOKENS = 1;
8
9
  }
@@ -3,6 +3,7 @@ pragma solidity 0.8.28;
3
3
 
4
4
  import {JBDeadline} from "../JBDeadline.sol";
5
5
 
6
+ /// @notice A reusable deadline implementation with a fixed one-day duration.
6
7
  contract JBDeadline1Day is JBDeadline {
7
8
  constructor() JBDeadline(1 days) {}
8
9
  }
@@ -3,6 +3,7 @@ pragma solidity 0.8.28;
3
3
 
4
4
  import {JBDeadline} from "../JBDeadline.sol";
5
5
 
6
+ /// @notice A reusable deadline implementation with a fixed three-day duration.
6
7
  contract JBDeadline3Days is JBDeadline {
7
8
  constructor() JBDeadline(3 days) {}
8
9
  }
@@ -3,6 +3,7 @@ pragma solidity 0.8.28;
3
3
 
4
4
  import {JBDeadline} from "../JBDeadline.sol";
5
5
 
6
+ /// @notice A reusable deadline implementation with a fixed three-hour duration.
6
7
  contract JBDeadline3Hours is JBDeadline {
7
8
  constructor() JBDeadline(3 hours) {}
8
9
  }
@@ -3,6 +3,7 @@ pragma solidity 0.8.28;
3
3
 
4
4
  import {JBDeadline} from "../JBDeadline.sol";
5
5
 
6
+ /// @notice A reusable deadline implementation with a fixed seven-day duration.
6
7
  contract JBDeadline7Days is JBDeadline {
7
8
  constructor() JBDeadline(7 days) {}
8
9
  }