@bananapus/core-v6 0.0.15 → 0.0.16

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.
Files changed (212) hide show
  1. package/ADMINISTRATION.md +4 -0
  2. package/README.md +2 -2
  3. package/SKILLS.md +2 -0
  4. package/STYLE_GUIDE.md +16 -2
  5. package/package.json +2 -2
  6. package/script/Deploy.s.sol +22 -13
  7. package/script/DeployPeriphery.s.sol +70 -52
  8. package/script/helpers/CoreDeploymentLib.sol +83 -35
  9. package/src/JBChainlinkV3PriceFeed.sol +1 -0
  10. package/src/JBController.sol +18 -3
  11. package/src/JBERC20.sol +12 -3
  12. package/src/JBFundAccessLimits.sol +12 -2
  13. package/src/JBMultiTerminal.sol +3 -1
  14. package/src/JBPermissions.sol +1 -0
  15. package/src/JBProjects.sol +1 -1
  16. package/src/JBRulesets.sol +11 -0
  17. package/src/JBSplits.sol +5 -0
  18. package/src/JBTerminalStore.sol +3 -0
  19. package/src/JBTokens.sol +40 -4
  20. package/src/interfaces/IJBController.sol +6 -0
  21. package/src/interfaces/IJBPermitTerminal.sol +1 -0
  22. package/src/interfaces/IJBToken.sol +5 -0
  23. package/src/interfaces/IJBTokens.sol +13 -0
  24. package/src/libraries/JBMetadataResolver.sol +7 -3
  25. package/src/libraries/JBRulesetMetadataResolver.sol +21 -21
  26. package/src/structs/JBAccountingContext.sol +1 -0
  27. package/src/structs/JBAfterCashOutRecordedContext.sol +1 -0
  28. package/src/structs/JBAfterPayRecordedContext.sol +1 -0
  29. package/src/structs/JBBeforeCashOutRecordedContext.sol +1 -0
  30. package/src/structs/JBBeforePayRecordedContext.sol +1 -0
  31. package/src/structs/JBCashOutHookSpecification.sol +1 -0
  32. package/src/structs/JBCurrencyAmount.sol +1 -0
  33. package/src/structs/JBFee.sol +1 -0
  34. package/src/structs/JBFundAccessLimitGroup.sol +1 -0
  35. package/src/structs/JBPayHookSpecification.sol +1 -0
  36. package/src/structs/JBPermissionsData.sol +1 -0
  37. package/src/structs/JBRuleset.sol +1 -0
  38. package/src/structs/JBRulesetConfig.sol +1 -0
  39. package/src/structs/JBRulesetMetadata.sol +1 -0
  40. package/src/structs/JBRulesetWeightCache.sol +1 -0
  41. package/src/structs/JBRulesetWithMetadata.sol +1 -0
  42. package/src/structs/JBSingleAllowance.sol +1 -0
  43. package/src/structs/JBSplit.sol +1 -0
  44. package/src/structs/JBSplitGroup.sol +1 -0
  45. package/src/structs/JBSplitHookContext.sol +1 -0
  46. package/src/structs/JBTerminalConfig.sol +1 -0
  47. package/src/structs/JBTokenAmount.sol +1 -0
  48. package/test/ComprehensiveInvariant.t.sol +15 -2
  49. package/test/CoreExploitTests.t.sol +34 -1
  50. package/test/EconomicSimulation.t.sol +10 -2
  51. package/test/EntryPointPermutations.t.sol +17 -3
  52. package/test/FlashLoanAttacks.t.sol +12 -1
  53. package/test/PermissionEscalation.t.sol +53 -10
  54. package/test/RulesetTransitions.t.sol +15 -1
  55. package/test/SplitLoopTests.t.sol +25 -2
  56. package/test/TestAccessToFunds.sol +17 -2
  57. package/test/TestCashOut.sol +15 -1
  58. package/test/TestCashOutCountFor.sol +1 -1
  59. package/test/TestCashOutHooks.sol +47 -25
  60. package/test/TestCashOutTimingEdge.sol +13 -1
  61. package/test/TestDurationUnderflow.sol +13 -1
  62. package/test/TestFeeProcessingFailure.sol +16 -1
  63. package/test/TestFees.sol +14 -1
  64. package/test/TestInterfaceSupport.sol +20 -1
  65. package/test/TestJBERC20Inheritance.sol +11 -1
  66. package/test/TestLaunchProject.sol +13 -1
  67. package/test/TestMetaTx.sol +15 -1
  68. package/test/TestMetadataParserLib.sol +37 -4
  69. package/test/TestMigrationHeldFees.sol +16 -1
  70. package/test/TestMintTokensOf.sol +14 -1
  71. package/test/TestMultiTokenSurplus.sol +14 -1
  72. package/test/TestMultipleAccessLimits.sol +23 -1
  73. package/test/TestPayBurnRedeemFlow.sol +16 -1
  74. package/test/TestPayHooks.sol +33 -14
  75. package/test/TestPermissions.sol +20 -1
  76. package/test/TestPermissionsEdge.sol +5 -1
  77. package/test/TestPermit2Terminal.sol +36 -3
  78. package/test/TestRulesetQueueing.sol +24 -1
  79. package/test/TestRulesetQueuingStress.sol +20 -1
  80. package/test/TestRulesetWeightCaching.sol +5 -1
  81. package/test/TestSplits.sol +23 -1
  82. package/test/TestTerminalMigration.sol +11 -1
  83. package/test/TestTokenFlow.sol +18 -1
  84. package/test/TestWeightCacheStaleAfterRejection.sol +15 -1
  85. package/test/WeirdTokenTests.t.sol +17 -1
  86. package/test/fork/TestChainlinkPriceFeedFork.sol +6 -1
  87. package/test/formal/BondingCurveProperties.t.sol +8 -1
  88. package/test/formal/FeeProperties.t.sol +7 -1
  89. package/test/helpers/JBTest.sol +1 -1
  90. package/test/helpers/TestBaseWorkflow.sol +84 -1
  91. package/test/invariants/Phase3DeepInvariant.t.sol +13 -2
  92. package/test/invariants/RulesetsInvariant.t.sol +12 -2
  93. package/test/invariants/TerminalStoreInvariant.t.sol +11 -2
  94. package/test/invariants/TokensInvariant.t.sol +13 -2
  95. package/test/invariants/handlers/ComprehensiveHandler.sol +19 -1
  96. package/test/invariants/handlers/EconomicHandler.sol +31 -1
  97. package/test/invariants/handlers/Phase3Handler.sol +31 -1
  98. package/test/invariants/handlers/RulesetsHandler.sol +5 -1
  99. package/test/invariants/handlers/TerminalStoreHandler.sol +6 -1
  100. package/test/invariants/handlers/TokensHandler.sol +1 -1
  101. package/test/mock/MockERC20.sol +0 -2
  102. package/test/mock/MockMaliciousBeneficiary.sol +2 -1
  103. package/test/mock/MockMaliciousSplitHook.sol +2 -1
  104. package/test/mock/MockPriceFeed.sol +1 -1
  105. package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +0 -1
  106. package/test/units/static/JBController/JBControllerSetup.sol +10 -1
  107. package/test/units/static/JBController/TestBurnTokensOf.sol +8 -1
  108. package/test/units/static/JBController/TestClaimTokensFor.sol +4 -1
  109. package/test/units/static/JBController/TestDeployErc20For.sol +7 -1
  110. package/test/units/static/JBController/TestLaunchProjectFor.sol +21 -1
  111. package/test/units/static/JBController/TestLaunchRulesetsFor.sol +21 -1
  112. package/test/units/static/JBController/TestMigrateController.sol +10 -1
  113. package/test/units/static/JBController/TestMintTokensOfUnits.sol +10 -1
  114. package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +4 -1
  115. package/test/units/static/JBController/TestReceiveMigrationFrom.sol +5 -1
  116. package/test/units/static/JBController/TestRulesetViews.sol +7 -1
  117. package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +21 -1
  118. package/test/units/static/JBController/TestSetSplitGroupsOf.sol +6 -1
  119. package/test/units/static/JBController/TestSetTokenFor.sol +13 -1
  120. package/test/units/static/JBController/TestSetUriOf.sol +5 -1
  121. package/test/units/static/JBController/TestTransferCreditsFrom.sol +11 -1
  122. package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +12 -1
  123. package/test/units/static/JBDirectory/JBDirectorySetup.sol +4 -1
  124. package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +5 -1
  125. package/test/units/static/JBDirectory/TestSetControllerOf.sol +11 -1
  126. package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +7 -1
  127. package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +11 -1
  128. package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +10 -1
  129. package/test/units/static/JBERC20/JBERC20Setup.sol +2 -1
  130. package/test/units/static/JBERC20/SigUtils.sol +2 -0
  131. package/test/units/static/JBERC20/TestInitialize.sol +1 -1
  132. package/test/units/static/JBERC20/TestName.sol +1 -1
  133. package/test/units/static/JBERC20/TestNonces.sol +3 -1
  134. package/test/units/static/JBERC20/TestSymbol.sol +1 -1
  135. package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +2 -1
  136. package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +2 -1
  137. package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +1 -1
  138. package/test/units/static/JBFees/TestFeesFuzz.sol +1 -1
  139. package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +0 -1
  140. package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +0 -1
  141. package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +3 -1
  142. package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +4 -1
  143. package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +4 -1
  144. package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +8 -1
  145. package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +8 -1
  146. package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +4 -1
  147. package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +7 -1
  148. package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +1 -1
  149. package/test/units/static/JBMetadataResolver/TestMetadataResolverEdgeCases.sol +2 -1
  150. package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +2 -1
  151. package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +12 -1
  152. package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +9 -1
  153. package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +18 -2
  154. package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +42 -7
  155. package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +30 -6
  156. package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +18 -2
  157. package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +13 -3
  158. package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +21 -4
  159. package/test/units/static/JBMultiTerminal/TestPay.sol +32 -6
  160. package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +0 -1
  161. package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +15 -1
  162. package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +17 -1
  163. package/test/units/static/JBPermissions/JBPermissionsSetup.sol +2 -1
  164. package/test/units/static/JBPermissions/TestHasPermission.sol +1 -1
  165. package/test/units/static/JBPermissions/TestHasPermissions.sol +1 -1
  166. package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +3 -1
  167. package/test/units/static/JBPrices/JBPricesSetup.sol +6 -1
  168. package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +6 -1
  169. package/test/units/static/JBPrices/TestPricePerUnitOf.sol +4 -1
  170. package/test/units/static/JBPrices/TestPrices.sol +4 -1
  171. package/test/units/static/JBProjects/JBProjectsSetup.sol +2 -1
  172. package/test/units/static/JBProjects/TestCreateFor.sol +3 -1
  173. package/test/units/static/JBProjects/TestInitialProject.sol +2 -1
  174. package/test/units/static/JBProjects/TestInterfaces.sol +0 -1
  175. package/test/units/static/JBProjects/TestSetResolver.sol +2 -1
  176. package/test/units/static/JBProjects/TestTokenUri.sol +3 -1
  177. package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +9 -1
  178. package/test/units/static/JBRulesets/JBRulesetsSetup.sol +3 -1
  179. package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +9 -1
  180. package/test/units/static/JBRulesets/TestCurrentOf.sol +10 -1
  181. package/test/units/static/JBRulesets/TestGetRulesetOf.sol +7 -1
  182. package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +9 -1
  183. package/test/units/static/JBRulesets/TestRulesets.sol +12 -1
  184. package/test/units/static/JBRulesets/TestRulesetsOf.sol +1 -1
  185. package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +10 -1
  186. package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +6 -1
  187. package/test/units/static/JBSplits/JBSplitsSetup.sol +3 -1
  188. package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +8 -1
  189. package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +8 -1
  190. package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +6 -1
  191. package/test/units/static/JBSplits/TestSplitsOf.sol +1 -1
  192. package/test/units/static/JBSplits/TestSplitsPacking.sol +5 -2
  193. package/test/units/static/JBSurplus/TestSurplusFuzz.sol +3 -1
  194. package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +5 -1
  195. package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +14 -1
  196. package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +14 -1
  197. package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +3 -1
  198. package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +20 -1
  199. package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +15 -1
  200. package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +13 -1
  201. package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +8 -1
  202. package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +16 -1
  203. package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +15 -1
  204. package/test/units/static/JBTokens/JBTokensSetup.sol +5 -1
  205. package/test/units/static/JBTokens/TestBurnFrom.sol +4 -1
  206. package/test/units/static/JBTokens/TestClaimTokensFor.sol +4 -1
  207. package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +4 -1
  208. package/test/units/static/JBTokens/TestMintFor.sol +4 -1
  209. package/test/units/static/JBTokens/TestSetTokenFor.sol +4 -1
  210. package/test/units/static/JBTokens/TestTotalBalanceOf.sol +1 -1
  211. package/test/units/static/JBTokens/TestTotalSupplyOf.sol +1 -1
  212. package/test/units/static/JBTokens/TestTransferCreditsFrom.sol +3 -1
@@ -336,7 +336,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
336
336
  require(msg.sender == address(this));
337
337
 
338
338
  // Approve the tokens being paid.
339
- IERC20(address(token)).forceApprove(address(terminal), splitTokenCount);
339
+ IERC20(address(token)).forceApprove({spender: address(terminal), value: splitTokenCount});
340
340
 
341
341
  // slither-disable-next-line unused-return
342
342
  terminal.pay({
@@ -350,7 +350,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
350
350
  });
351
351
 
352
352
  // Make sure that the terminal received the tokens.
353
- if (IERC20(address(token)).allowance(address(this), address(terminal)) != 0) {
353
+ if (IERC20(address(token)).allowance({owner: address(this), spender: address(terminal)}) != 0) {
354
354
  revert JBController_TerminalTokensNotTransferred();
355
355
  }
356
356
  }
@@ -646,6 +646,21 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
646
646
  TOKENS.setTokenFor({projectId: projectId, token: token});
647
647
  }
648
648
 
649
+ /// @notice Sets the name and symbol of a project's token.
650
+ /// @dev Can only be called by the project's owner or an address with the owner's permission to
651
+ /// `SET_TOKEN_METADATA`.
652
+ /// @param projectId The ID of the project whose token is being updated.
653
+ /// @param name The new name.
654
+ /// @param symbol The new symbol.
655
+ function setTokenMetadataOf(uint256 projectId, string calldata name, string calldata symbol) external override {
656
+ // Enforce permissions.
657
+ _requirePermissionFrom({
658
+ account: PROJECTS.ownerOf(projectId), projectId: projectId, permissionId: JBPermissionIds.SET_TOKEN_METADATA
659
+ });
660
+
661
+ TOKENS.setTokenMetadataFor({projectId: projectId, name: name, symbol: symbol});
662
+ }
663
+
649
664
  /// @notice Set a project's metadata URI.
650
665
  /// @dev This is typically an IPFS hash, optionally with an `ipfs://` prefix.
651
666
  /// @dev Can only be called by the project's owner or an address with the owner's permission to
@@ -1026,7 +1041,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
1026
1041
  });
1027
1042
 
1028
1043
  // If it fails, transfer the tokens from this contract to the beneficiary.
1029
- IERC20(address(token)).safeTransfer(beneficiary, splitTokenCount);
1044
+ IERC20(address(token)).safeTransfer({to: beneficiary, value: splitTokenCount});
1030
1045
  }
1031
1046
  }
1032
1047
  } else if (beneficiary == address(0xdead)) {
package/src/JBERC20.sol CHANGED
@@ -47,7 +47,7 @@ contract JBERC20 is ERC20Votes, ERC20Permit, Ownable, IJBToken {
47
47
  /// @param account The address to burn tokens from.
48
48
  /// @param amount The amount of tokens to burn, as a fixed point number with 18 decimals.
49
49
  function burn(address account, uint256 amount) external override onlyOwner {
50
- return _burn(account, amount);
50
+ return _burn({account: account, value: amount});
51
51
  }
52
52
 
53
53
  /// @notice Mints more of this token.
@@ -55,7 +55,16 @@ contract JBERC20 is ERC20Votes, ERC20Permit, Ownable, IJBToken {
55
55
  /// @param account The address to mint the new tokens to.
56
56
  /// @param amount The amount of tokens to mint, as a fixed point number with 18 decimals.
57
57
  function mint(address account, uint256 amount) external override onlyOwner {
58
- return _mint(account, amount);
58
+ return _mint({account: account, value: amount});
59
+ }
60
+
61
+ /// @notice Sets the token's name and symbol.
62
+ /// @dev Can only be called by this contract's owner.
63
+ /// @param name_ The new name.
64
+ /// @param symbol_ The new symbol.
65
+ function setMetadata(string memory name_, string memory symbol_) external override onlyOwner {
66
+ _name = name_;
67
+ _symbol = symbol_;
59
68
  }
60
69
 
61
70
  //*********************************************************************//
@@ -130,6 +139,6 @@ contract JBERC20 is ERC20Votes, ERC20Permit, Ownable, IJBToken {
130
139
 
131
140
  /// @notice Required override.
132
141
  function _update(address from, address to, uint256 value) internal virtual override(ERC20, ERC20Votes) {
133
- super._update(from, to, value);
142
+ super._update({from: from, to: to, value: value});
134
143
  }
135
144
  }
@@ -177,6 +177,7 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
177
177
 
178
178
  // If the currencies match, return the value.
179
179
  if (currency == packedPayoutLimitData >> 224) {
180
+ // forge-lint: disable-next-line(unsafe-typecast)
180
181
  return uint256(uint224(packedPayoutLimitData));
181
182
  }
182
183
  }
@@ -217,8 +218,12 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
217
218
  uint256 packedPayoutLimitData = packedPayoutLimitsData[i];
218
219
 
219
220
  // The limit amount is in bits 0-223. The currency is in bits 224-255.
221
+ // forge-lint: disable-next-line(unsafe-typecast)
220
222
  payoutLimits[i] = JBCurrencyAmount({
221
- currency: uint32(packedPayoutLimitData >> 224), amount: uint224(packedPayoutLimitData)
223
+ // forge-lint: disable-next-line(unsafe-typecast)
224
+ currency: uint32(packedPayoutLimitData >> 224),
225
+ // forge-lint: disable-next-line(unsafe-typecast)
226
+ amount: uint224(packedPayoutLimitData)
222
227
  });
223
228
  }
224
229
  }
@@ -258,6 +263,7 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
258
263
 
259
264
  // If the currencies match, return the value.
260
265
  if (currency == packedSurplusAllowanceData >> 224) {
266
+ // forge-lint: disable-next-line(unsafe-typecast)
261
267
  return uint256(uint224(packedSurplusAllowanceData));
262
268
  }
263
269
  }
@@ -300,8 +306,12 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
300
306
  uint256 packedSurplusAllowanceData = packedSurplusAllowancesData[i];
301
307
 
302
308
  // The limit is in bits 0-223. The currency is in bits 224-255.
309
+ // forge-lint: disable-next-line(unsafe-typecast)
303
310
  surplusAllowances[i] = JBCurrencyAmount({
304
- currency: uint32(packedSurplusAllowanceData >> 224), amount: uint224(packedSurplusAllowanceData)
311
+ // forge-lint: disable-next-line(unsafe-typecast)
312
+ currency: uint32(packedSurplusAllowanceData >> 224),
313
+ // forge-lint: disable-next-line(unsafe-typecast)
314
+ amount: uint224(packedSurplusAllowanceData)
305
315
  });
306
316
  }
307
317
  }
@@ -1834,6 +1834,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
1834
1834
  JBFee({
1835
1835
  amount: amount,
1836
1836
  beneficiary: beneficiary,
1837
+ // forge-lint: disable-next-line(unsafe-typecast)
1837
1838
  unlockTimestamp: uint48(block.timestamp + _FEE_HOLDING_SECONDS)
1838
1839
  })
1839
1840
  );
@@ -1877,7 +1878,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
1877
1878
  }
1878
1879
 
1879
1880
  // If there's sufficient approval, transfer normally.
1880
- if (IERC20(token).allowance(address(from), address(this)) >= amount) {
1881
+ if (IERC20(token).allowance({owner: address(from), spender: address(this)}) >= amount) {
1881
1882
  return IERC20(token).safeTransferFrom({from: from, to: to, value: amount});
1882
1883
  }
1883
1884
 
@@ -1885,6 +1886,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
1885
1886
  if (amount > type(uint160).max) revert JBMultiTerminal_OverflowAlert(amount, type(uint160).max);
1886
1887
 
1887
1888
  // Otherwise we attempt to use the PERMIT2 method.
1889
+ // forge-lint: disable-next-line(unsafe-typecast)
1888
1890
  PERMIT2.transferFrom({from: from, to: to, amount: uint160(amount), token: token});
1889
1891
  }
1890
1892
 
@@ -250,6 +250,7 @@ contract JBPermissions is ERC2771Context, IJBPermissions {
250
250
  uint256 permissionId = permissionIds[i];
251
251
 
252
252
  // Turn on the bit at the ID.
253
+ // forge-lint: disable-next-line(incorrect-shift)
253
254
  packed |= 1 << permissionId;
254
255
  }
255
256
  }
@@ -74,7 +74,7 @@ contract JBProjects is ERC721, ERC2771Context, Ownable, IJBProjects {
74
74
  emit Create({projectId: projectId, owner: owner, caller: _msgSender()});
75
75
 
76
76
  // Mint the project.
77
- _safeMint(owner, projectId);
77
+ _safeMint({to: owner, tokenId: projectId});
78
78
  }
79
79
 
80
80
  //*********************************************************************//
@@ -247,6 +247,7 @@ contract JBRulesets is JBControlled, IJBRulesets {
247
247
  // Calculate the weight cut multiple.
248
248
  uint168 weightCutMultiple;
249
249
  unchecked {
250
+ // forge-lint: disable-next-line(unsafe-typecast)
250
251
  weightCutMultiple = uint168(startDistance / targetRuleset.duration);
251
252
  }
252
253
 
@@ -955,26 +956,34 @@ contract JBRulesets is JBControlled, IJBRulesets {
955
956
  // slither-disable-next-line incorrect-equality
956
957
  if (rulesetId == 0) return ruleset;
957
958
 
959
+ // forge-lint: disable-next-line(unsafe-typecast)
958
960
  ruleset.id = uint48(rulesetId);
959
961
 
960
962
  uint256 packedIntrinsicProperties = _packedIntrinsicPropertiesOf[projectId][rulesetId];
961
963
 
962
964
  // `weight` in bits 0-111 bits.
965
+ // forge-lint: disable-next-line(unsafe-typecast)
963
966
  ruleset.weight = uint112(packedIntrinsicProperties);
964
967
  // `basedOnId` in bits 112-159 bits.
968
+ // forge-lint: disable-next-line(unsafe-typecast)
965
969
  ruleset.basedOnId = uint48(packedIntrinsicProperties >> 112);
966
970
  // `start` in bits 160-207 bits.
971
+ // forge-lint: disable-next-line(unsafe-typecast)
967
972
  ruleset.start = uint48(packedIntrinsicProperties >> 160);
968
973
  // `cycleNumber` in bits 208-255 bits.
974
+ // forge-lint: disable-next-line(unsafe-typecast)
969
975
  ruleset.cycleNumber = uint48(packedIntrinsicProperties >> 208);
970
976
 
971
977
  uint256 packedUserProperties = _packedUserPropertiesOf[projectId][rulesetId];
972
978
 
973
979
  // approval hook in bits 0-159 bits.
980
+ // forge-lint: disable-next-line(unsafe-typecast)
974
981
  ruleset.approvalHook = IJBRulesetApprovalHook(address(uint160(packedUserProperties)));
975
982
  // `duration` in bits 160-191 bits.
983
+ // forge-lint: disable-next-line(unsafe-typecast)
976
984
  ruleset.duration = uint32(packedUserProperties >> 160);
977
985
  // weight cut percent in bits 192-223 bits.
986
+ // forge-lint: disable-next-line(unsafe-typecast)
978
987
  ruleset.weightCutPercent = uint32(packedUserProperties >> 192);
979
988
 
980
989
  ruleset.metadata = _metadataOf[projectId][rulesetId];
@@ -1021,9 +1030,11 @@ contract JBRulesets is JBControlled, IJBRulesets {
1021
1030
  });
1022
1031
 
1023
1032
  return JBRuleset({
1033
+ // forge-lint: disable-next-line(unsafe-typecast)
1024
1034
  cycleNumber: uint48(rulesetCycleNumber),
1025
1035
  id: baseRuleset.id,
1026
1036
  basedOnId: baseRuleset.basedOnId,
1037
+ // forge-lint: disable-next-line(unsafe-typecast)
1027
1038
  start: uint48(start),
1028
1039
  duration: baseRuleset.duration,
1029
1040
  weight: uint112(
package/src/JBSplits.sol CHANGED
@@ -271,10 +271,13 @@ contract JBSplits is JBControlled, IJBSplits {
271
271
  JBSplit memory split;
272
272
 
273
273
  // `percent` in bits 0-31.
274
+ // forge-lint: disable-next-line(unsafe-typecast)
274
275
  split.percent = uint32(packedSplitPart1);
275
276
  // `projectId` in bits 32-95.
277
+ // forge-lint: disable-next-line(unsafe-typecast)
276
278
  split.projectId = uint64(packedSplitPart1 >> 32);
277
279
  // `beneficiary` in bits 96-255.
280
+ // forge-lint: disable-next-line(unsafe-typecast)
278
281
  split.beneficiary = payable(address(uint160(packedSplitPart1 >> 96)));
279
282
 
280
283
  // Get a reference to the second part of the split's packed data.
@@ -285,8 +288,10 @@ contract JBSplits is JBControlled, IJBSplits {
285
288
  // `preferAddToBalance` in bit 0.
286
289
  split.preferAddToBalance = packedSplitPart2 & 1 == 1;
287
290
  // `lockedUntil` in bits 1-48.
291
+ // forge-lint: disable-next-line(unsafe-typecast)
288
292
  split.lockedUntil = uint48(packedSplitPart2 >> 1);
289
293
  // `hook` in bits 49-208.
294
+ // forge-lint: disable-next-line(unsafe-typecast)
290
295
  split.hook = IJBSplitHook(address(uint160(packedSplitPart2 >> 49)));
291
296
  }
292
297
 
@@ -868,6 +868,7 @@ contract JBTerminalStore is IJBTerminalStore {
868
868
  terminal
869
869
  ][projectId][accountingContext.token][ruleset.cycleNumber][payoutLimit.currency];
870
870
  if (remaining > type(uint224).max) revert JBTerminalStore_Uint224Overflow(remaining);
871
+ // forge-lint: disable-next-line(unsafe-typecast)
871
872
  payoutLimit.amount = uint224(remaining);
872
873
  }
873
874
 
@@ -877,6 +878,7 @@ contract JBTerminalStore is IJBTerminalStore {
877
878
  value: payoutLimit.amount, decimals: accountingContext.decimals, targetDecimals: targetDecimals
878
879
  });
879
880
  if (adjusted > type(uint224).max) revert JBTerminalStore_Uint224Overflow(adjusted);
881
+ // forge-lint: disable-next-line(unsafe-typecast)
880
882
  payoutLimit.amount = uint224(adjusted);
881
883
  }
882
884
 
@@ -894,6 +896,7 @@ contract JBTerminalStore is IJBTerminalStore {
894
896
  })
895
897
  );
896
898
  if (converted > type(uint224).max) revert JBTerminalStore_Uint224Overflow(converted);
899
+ // forge-lint: disable-next-line(unsafe-typecast)
897
900
  payoutLimit.amount = uint224(converted);
898
901
  }
899
902
 
package/src/JBTokens.sol CHANGED
@@ -128,7 +128,7 @@ contract JBTokens is JBControlled, IJBTokens {
128
128
  });
129
129
 
130
130
  // Burn the tokens.
131
- if (tokensToBurn > 0) token.burn(holder, tokensToBurn);
131
+ if (tokensToBurn > 0) token.burn({account: holder, amount: tokensToBurn});
132
132
  }
133
133
 
134
134
  /// @notice Redeem credits to claim tokens into a holder's wallet.
@@ -177,7 +177,7 @@ contract JBTokens is JBControlled, IJBTokens {
177
177
  });
178
178
 
179
179
  // Mint the equivalent amount of the project's token for the holder.
180
- token.mint(beneficiary, count);
180
+ token.mint({account: beneficiary, amount: count});
181
181
  }
182
182
 
183
183
  /// @notice Deploys an ERC-20 token for a project. It will be used when claiming tokens.
@@ -211,7 +211,11 @@ contract JBTokens is JBControlled, IJBTokens {
211
211
 
212
212
  token = salt == bytes32(0)
213
213
  ? IJBToken(Clones.clone(address(TOKEN)))
214
- : IJBToken(Clones.cloneDeterministic(address(TOKEN), keccak256(abi.encode(msg.sender, salt))));
214
+ : IJBToken(
215
+ Clones.cloneDeterministic({
216
+ implementation: address(TOKEN), salt: keccak256(abi.encode(msg.sender, salt))
217
+ })
218
+ );
215
219
 
216
220
  // Store the token contract.
217
221
  tokenOf[projectId] = token;
@@ -257,7 +261,7 @@ contract JBTokens is JBControlled, IJBTokens {
257
261
  if (tokensWereClaimed) {
258
262
  // If tokens should be claimed, mint tokens into the holder's wallet.
259
263
  // slither-disable-next-line reentrancy-events
260
- token.mint(holder, count);
264
+ token.mint({account: holder, amount: count});
261
265
  } else {
262
266
  // Otherwise, add the tokens to their credits and the credit supply.
263
267
  creditBalanceOf[holder][projectId] += count;
@@ -298,6 +302,38 @@ contract JBTokens is JBControlled, IJBTokens {
298
302
  emit SetToken({projectId: projectId, token: token, caller: msg.sender});
299
303
  }
300
304
 
305
+ /// @notice Sets the name and symbol of a project's token.
306
+ /// @dev Only a project's controller can set the token's name and symbol.
307
+ /// @param projectId The ID of the project whose token is being updated.
308
+ /// @param name The new name.
309
+ /// @param symbol The new symbol.
310
+ function setTokenMetadataFor(
311
+ uint256 projectId,
312
+ string calldata name,
313
+ string calldata symbol
314
+ )
315
+ external
316
+ override
317
+ onlyControllerOf(projectId)
318
+ {
319
+ // Get a reference to the project's current token.
320
+ IJBToken token = tokenOf[projectId];
321
+
322
+ // The project must have a token contract attached.
323
+ if (token == IJBToken(address(0))) revert JBTokens_TokenNotFound();
324
+
325
+ // There must be a name.
326
+ if (bytes(name).length == 0) revert JBTokens_EmptyName();
327
+
328
+ // There must be a symbol.
329
+ if (bytes(symbol).length == 0) revert JBTokens_EmptySymbol();
330
+
331
+ emit SetTokenMetadata({projectId: projectId, name: name, symbol: symbol, caller: msg.sender});
332
+
333
+ // Set the name and symbol.
334
+ token.setMetadata({name: name, symbol: symbol});
335
+ }
336
+
301
337
  /// @notice Allows a holder to transfer credits to another account.
302
338
  /// @dev Only a project's controller can transfer credits for that project.
303
339
  /// @param holder The address to transfer credits from.
@@ -345,6 +345,12 @@ interface IJBController is IERC165, IJBProjectUriRegistry, IJBDirectoryAccessCon
345
345
  /// @param token The new token's address.
346
346
  function setTokenFor(uint256 projectId, IJBToken token) external;
347
347
 
348
+ /// @notice Sets the name and symbol of a project's token.
349
+ /// @param projectId The ID of the project whose token is being updated.
350
+ /// @param name The new name.
351
+ /// @param symbol The new symbol.
352
+ function setTokenMetadataOf(uint256 projectId, string calldata name, string calldata symbol) external;
353
+
348
354
  /// @notice Transfers credits from one address to another.
349
355
  /// @param holder The address to transfer credits from.
350
356
  /// @param projectId The ID of the project whose credits are being transferred.
@@ -14,5 +14,6 @@ interface IJBPermitTerminal is IJBTerminal {
14
14
  event Permit2AllowanceFailed(address indexed token, address indexed owner, bytes reason);
15
15
 
16
16
  /// @notice The Permit2 contract used for token approvals.
17
+ // forge-lint: disable-next-line(mixed-case-function)
17
18
  function PERMIT2() external returns (IPermit2);
18
19
  }
@@ -36,4 +36,9 @@ interface IJBToken {
36
36
  /// @param account The address to mint tokens to.
37
37
  /// @param amount The amount of tokens to mint.
38
38
  function mint(address account, uint256 amount) external;
39
+
40
+ /// @notice Sets the token's name and symbol.
41
+ /// @param name The new name.
42
+ /// @param symbol The new symbol.
43
+ function setMetadata(string memory name, string memory symbol) external;
39
44
  }
@@ -64,6 +64,13 @@ interface IJBTokens {
64
64
  /// @param caller The address that set the token.
65
65
  event SetToken(uint256 indexed projectId, IJBToken indexed token, address caller);
66
66
 
67
+ /// @notice A project token's name and symbol were updated.
68
+ /// @param projectId The ID of the project whose token was updated.
69
+ /// @param name The new token name.
70
+ /// @param symbol The new token symbol.
71
+ /// @param caller The address that called the function.
72
+ event SetTokenMetadata(uint256 indexed projectId, string name, string symbol, address caller);
73
+
67
74
  /// @notice Credits were transferred from one holder to another.
68
75
  /// @param holder The address that transferred the credits.
69
76
  /// @param projectId The ID of the project whose credits were transferred.
@@ -146,6 +153,12 @@ interface IJBTokens {
146
153
  /// @param token The token to set.
147
154
  function setTokenFor(uint256 projectId, IJBToken token) external;
148
155
 
156
+ /// @notice Sets the name and symbol of a project's token.
157
+ /// @param projectId The ID of the project whose token is being updated.
158
+ /// @param name The new name.
159
+ /// @param symbol The new symbol.
160
+ function setTokenMetadataFor(uint256 projectId, string calldata name, string calldata symbol) external;
161
+
149
162
  /// @notice Transfers credits from one holder to another.
150
163
  /// @param holder The address to transfer credits from.
151
164
  /// @param projectId The ID of the project whose credits are being transferred.
@@ -62,6 +62,7 @@ library JBMetadataResolver {
62
62
  {
63
63
  // Empty original metadata and maybe something in the first 32 bytes: create new metadata
64
64
  if (originalMetadata.length <= RESERVED_SIZE) {
65
+ // forge-lint: disable-next-line(unsafe-typecast)
65
66
  return abi.encodePacked(bytes32(originalMetadata), bytes32(abi.encodePacked(idToAdd, uint8(2))), dataToAdd);
66
67
  }
67
68
 
@@ -96,7 +97,7 @@ library JBMetadataResolver {
96
97
  numberOfWordslastData = (originalMetadata.length - lastOffset * WORD_SIZE) / WORD_SIZE;
97
98
 
98
99
  // Copy the reserved word and the table and remove the previous padding
99
- newMetadata = _sliceBytes(originalMetadata, 0, lastOffsetIndex + 1);
100
+ newMetadata = _sliceBytes({data: originalMetadata, start: 0, end: lastOffsetIndex + 1});
100
101
 
101
102
  // Check if the new entry is still fitting in this word
102
103
  if (i + TOTAL_ID_SIZE >= firstOffset * WORD_SIZE) {
@@ -118,6 +119,7 @@ library JBMetadataResolver {
118
119
  // Compute in uint256 first — casting directly to uint8 silently wraps offsets > 255.
119
120
  uint256 newOffset = lastOffset + numberOfWordslastData;
120
121
  if (newOffset > 255) revert JBMetadataResolver_MetadataTooLong();
122
+ // forge-lint: disable-next-line(unsafe-typecast)
121
123
  newMetadata = abi.encodePacked(newMetadata, idToAdd, bytes1(uint8(newOffset)));
122
124
 
123
125
  // Pad as needed - inlined for gas saving
@@ -129,7 +131,8 @@ library JBMetadataResolver {
129
131
 
130
132
  // Add existing data at the end
131
133
  newMetadata = abi.encodePacked(
132
- newMetadata, _sliceBytes(originalMetadata, firstOffset * WORD_SIZE, originalMetadata.length)
134
+ newMetadata,
135
+ _sliceBytes({data: originalMetadata, start: firstOffset * WORD_SIZE, end: originalMetadata.length})
133
136
  );
134
137
 
135
138
  // Pad as needed
@@ -181,6 +184,7 @@ library JBMetadataResolver {
181
184
  revert JBMetadataResolver_DataNotPadded();
182
185
  }
183
186
 
187
+ // forge-lint: disable-next-line(unsafe-typecast)
184
188
  metadata = abi.encodePacked(metadata, ids[i], bytes1(uint8(offset)));
185
189
  offset += data.length / JBMetadataResolver.WORD_SIZE;
186
190
 
@@ -244,7 +248,7 @@ library JBMetadataResolver {
244
248
  ? metadata.length
245
249
  : uint256(uint8(metadata[i + NEXT_ID_OFFSET])) * WORD_SIZE;
246
250
 
247
- return (true, _sliceBytes(metadata, currentOffset * WORD_SIZE, end));
251
+ return (true, _sliceBytes({data: metadata, start: currentOffset * WORD_SIZE, end: end}));
248
252
  }
249
253
  unchecked {
250
254
  i += TOTAL_ID_SIZE;
@@ -135,26 +135,26 @@ library JBRulesetMetadataResolver {
135
135
  /// @param ruleset The funding cycle having its metadata expanded.
136
136
  /// @return rulesetMetadata The ruleset's metadata object.
137
137
  function expandMetadata(JBRuleset memory ruleset) internal pure returns (JBRulesetMetadata memory) {
138
- return JBRulesetMetadata(
139
- reservedPercent(ruleset),
140
- cashOutTaxRate(ruleset),
141
- baseCurrency(ruleset),
142
- pausePay(ruleset),
143
- pauseCreditTransfers(ruleset),
144
- allowOwnerMinting(ruleset),
145
- allowSetCustomToken(ruleset),
146
- allowTerminalMigration(ruleset),
147
- allowSetTerminals(ruleset),
148
- allowSetController(ruleset),
149
- allowAddAccountingContext(ruleset),
150
- allowAddPriceFeed(ruleset),
151
- ownerMustSendPayouts(ruleset),
152
- holdFees(ruleset),
153
- useTotalSurplusForCashOuts(ruleset),
154
- useDataHookForPay(ruleset),
155
- useDataHookForCashOut(ruleset),
156
- dataHook(ruleset),
157
- metadata(ruleset)
158
- );
138
+ return JBRulesetMetadata({
139
+ reservedPercent: reservedPercent(ruleset),
140
+ cashOutTaxRate: cashOutTaxRate(ruleset),
141
+ baseCurrency: baseCurrency(ruleset),
142
+ pausePay: pausePay(ruleset),
143
+ pauseCreditTransfers: pauseCreditTransfers(ruleset),
144
+ allowOwnerMinting: allowOwnerMinting(ruleset),
145
+ allowSetCustomToken: allowSetCustomToken(ruleset),
146
+ allowTerminalMigration: allowTerminalMigration(ruleset),
147
+ allowSetTerminals: allowSetTerminals(ruleset),
148
+ allowSetController: allowSetController(ruleset),
149
+ allowAddAccountingContext: allowAddAccountingContext(ruleset),
150
+ allowAddPriceFeed: allowAddPriceFeed(ruleset),
151
+ ownerMustSendPayouts: ownerMustSendPayouts(ruleset),
152
+ holdFees: holdFees(ruleset),
153
+ useTotalSurplusForCashOuts: useTotalSurplusForCashOuts(ruleset),
154
+ useDataHookForPay: useDataHookForPay(ruleset),
155
+ useDataHookForCashOut: useDataHookForCashOut(ruleset),
156
+ dataHook: dataHook(ruleset),
157
+ metadata: metadata(ruleset)
158
+ });
159
159
  }
160
160
  }
@@ -5,6 +5,7 @@ pragma solidity ^0.8.0;
5
5
  /// @custom:member decimals The number of decimals expected in that token's fixed point accounting.
6
6
  /// @custom:member currency The currency that the token is priced in terms of. By convention, this is
7
7
  /// `uint32(uint160(tokenAddress))` for tokens, or a constant ID from e.g. `JBCurrencyIds` for other currencies.
8
+ // forge-lint: disable-next-line(pascal-case-struct)
8
9
  struct JBAccountingContext {
9
10
  address token;
10
11
  uint8 decimals;
@@ -16,6 +16,7 @@ import {JBTokenAmount} from "./JBTokenAmount.sol";
16
16
  /// @custom:member beneficiary The address the reclaimed amount will be sent to.
17
17
  /// @custom:member hookMetadata Extra data specified by the data hook, which is sent to the cash out hook.
18
18
  /// @custom:member cashOutMetadata Extra data specified by the account cashing out, which is sent to the cash out hook.
19
+ // forge-lint: disable-next-line(pascal-case-struct)
19
20
  struct JBAfterCashOutRecordedContext {
20
21
  address holder;
21
22
  uint256 projectId;
@@ -15,6 +15,7 @@ import {JBTokenAmount} from "./JBTokenAmount.sol";
15
15
  /// @custom:member beneficiary The address which receives any tokens this payment yields.
16
16
  /// @custom:member hookMetadata Extra data specified by the data hook, which is sent to the pay hook.
17
17
  /// @custom:member payerMetadata Extra data specified by the payer, which is sent to the pay hook.
18
+ // forge-lint: disable-next-line(pascal-case-struct)
18
19
  struct JBAfterPayRecordedContext {
19
20
  address payer;
20
21
  uint256 projectId;
@@ -17,6 +17,7 @@ import {JBTokenAmount} from "./JBTokenAmount.sol";
17
17
  /// @custom:member useTotalSurplus If surplus across all of a project's terminals is being used when making cash outs.
18
18
  /// @custom:member cashOutTaxRate The cash out tax rate of the ruleset the cash out is being made during.
19
19
  /// @custom:member metadata Extra data provided by the casher.
20
+ // forge-lint: disable-next-line(pascal-case-struct)
20
21
  struct JBBeforeCashOutRecordedContext {
21
22
  address terminal;
22
23
  address holder;
@@ -15,6 +15,7 @@ import {JBTokenAmount} from "./JBTokenAmount.sol";
15
15
  /// @custom:member weight The weight of the ruleset during which the payment is being made.
16
16
  /// @custom:member reservedPercent The reserved percent of the ruleset the payment is being made during.
17
17
  /// @custom:member metadata Extra data specified by the payer.
18
+ // forge-lint: disable-next-line(pascal-case-struct)
18
19
  struct JBBeforePayRecordedContext {
19
20
  address terminal;
20
21
  address payer;
@@ -8,6 +8,7 @@ import {IJBCashOutHook} from "../interfaces/IJBCashOutHook.sol";
8
8
  /// @custom:member hook The cash out hook to use when fulfilling this specification.
9
9
  /// @custom:member amount The amount to send to the hook.
10
10
  /// @custom:member metadata Metadata to pass to the hook.
11
+ // forge-lint: disable-next-line(pascal-case-struct)
11
12
  struct JBCashOutHookSpecification {
12
13
  IJBCashOutHook hook;
13
14
  uint256 amount;
@@ -4,6 +4,7 @@ pragma solidity ^0.8.0;
4
4
  /// @custom:member amount The amount of the currency.
5
5
  /// @custom:member currency The currency. By convention, this is `uint32(uint160(tokenAddress))` for tokens, or a
6
6
  /// constant ID from e.g. `JBCurrencyIds` for other currencies.
7
+ // forge-lint: disable-next-line(pascal-case-struct)
7
8
  struct JBCurrencyAmount {
8
9
  uint224 amount;
9
10
  uint32 currency;
@@ -5,6 +5,7 @@ pragma solidity ^0.8.0;
5
5
  /// decimals as the terminal in which this struct was created.
6
6
  /// @custom:member beneficiary The address that will receive the tokens that are minted as a result of the fee payment.
7
7
  /// @custom:member unlockTimestamp The timestamp at which the fee is unlocked and can be processed.
8
+ // forge-lint: disable-next-line(pascal-case-struct)
8
9
  struct JBFee {
9
10
  uint256 amount;
10
11
  address beneficiary;
@@ -20,6 +20,7 @@ import {JBCurrencyAmount} from "./JBCurrencyAmount.sol";
20
20
  /// @custom:member surplusAllowances An array of surplus allowances. The surplus allowances cumulatively dictates the
21
21
  /// maximum value of `token`s a project can pay out from its surplus (balance less payouts) in a terminal during a
22
22
  /// ruleset. Each surplus allowance can have a unique currency and amount.
23
+ // forge-lint: disable-next-line(pascal-case-struct)
23
24
  struct JBFundAccessLimitGroup {
24
25
  address terminal;
25
26
  address token;
@@ -8,6 +8,7 @@ import {IJBPayHook} from "../interfaces/IJBPayHook.sol";
8
8
  /// @custom:member hook The pay hook to use when fulfilling this specification.
9
9
  /// @custom:member amount The amount to send to the hook.
10
10
  /// @custom:member metadata Metadata to pass the hook.
11
+ // forge-lint: disable-next-line(pascal-case-struct)
11
12
  struct JBPayHookSpecification {
12
13
  IJBPayHook hook;
13
14
  uint256 amount;
@@ -6,6 +6,7 @@ pragma solidity ^0.8.0;
6
6
  /// permissions under this project's scope. An ID of 0 is a wildcard, which gives an operator permissions across all
7
7
  /// projects.
8
8
  /// @custom:member permissionIds The IDs of the permissions being given. See the `JBPermissionIds` library.
9
+ // forge-lint: disable-next-line(pascal-case-struct)
9
10
  struct JBPermissionsData {
10
11
  address operator;
11
12
  uint64 projectId;
@@ -29,6 +29,7 @@ import {IJBRulesetApprovalHook} from "./../interfaces/IJBRulesetApprovalHook.sol
29
29
  /// ruleset is rejected, it won't go into effect. An approval hook can be used to create rules which dictate how a
30
30
  /// project owner can change their ruleset over time.
31
31
  /// @custom:member metadata Extra data associated with a ruleset which can be used by other contracts.
32
+ // forge-lint: disable-next-line(pascal-case-struct)
32
33
  struct JBRuleset {
33
34
  uint48 cycleNumber;
34
35
  uint48 id;
@@ -31,6 +31,7 @@ import {JBSplitGroup} from "./JBSplitGroup.sol";
31
31
  /// its balance in each payment terminal while the ruleset is active. Amounts are fixed point numbers using the same
32
32
  /// number of decimals as the corresponding terminal. The `_payoutLimit` and `_surplusAllowance` parameters must fit in
33
33
  /// a `uint232`.
34
+ // forge-lint: disable-next-line(pascal-case-struct)
34
35
  struct JBRulesetConfig {
35
36
  uint48 mustStartAtOrAfter;
36
37
  uint32 duration;