@bananapus/core-v6 0.0.14 → 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 (216) 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 +150 -43
  5. package/foundry.toml +3 -3
  6. package/package.json +4 -4
  7. package/remappings.txt +1 -1
  8. package/script/Deploy.s.sol +23 -16
  9. package/script/DeployPeriphery.s.sol +71 -66
  10. package/script/helpers/CoreDeploymentLib.sol +84 -37
  11. package/src/JBChainlinkV3PriceFeed.sol +1 -0
  12. package/src/JBController.sol +19 -4
  13. package/src/JBERC20.sol +12 -3
  14. package/src/JBFundAccessLimits.sol +12 -2
  15. package/src/JBMultiTerminal.sol +3 -1
  16. package/src/JBPermissions.sol +1 -0
  17. package/src/JBProjects.sol +1 -1
  18. package/src/JBRulesets.sol +11 -0
  19. package/src/JBSplits.sol +5 -0
  20. package/src/JBTerminalStore.sol +3 -0
  21. package/src/JBTokens.sol +40 -4
  22. package/src/interfaces/IJBController.sol +6 -1
  23. package/src/interfaces/IJBPayoutTerminal.sol +0 -1
  24. package/src/interfaces/IJBPermitTerminal.sol +1 -0
  25. package/src/interfaces/IJBToken.sol +5 -0
  26. package/src/interfaces/IJBTokens.sol +13 -0
  27. package/src/libraries/JBMetadataResolver.sol +7 -3
  28. package/src/libraries/JBRulesetMetadataResolver.sol +21 -21
  29. package/src/structs/JBAccountingContext.sol +1 -0
  30. package/src/structs/JBAfterCashOutRecordedContext.sol +1 -0
  31. package/src/structs/JBAfterPayRecordedContext.sol +1 -0
  32. package/src/structs/JBBeforeCashOutRecordedContext.sol +1 -0
  33. package/src/structs/JBBeforePayRecordedContext.sol +1 -0
  34. package/src/structs/JBCashOutHookSpecification.sol +1 -0
  35. package/src/structs/JBCurrencyAmount.sol +1 -0
  36. package/src/structs/JBFee.sol +1 -0
  37. package/src/structs/JBFundAccessLimitGroup.sol +1 -0
  38. package/src/structs/JBPayHookSpecification.sol +1 -0
  39. package/src/structs/JBPermissionsData.sol +1 -0
  40. package/src/structs/JBRuleset.sol +1 -0
  41. package/src/structs/JBRulesetConfig.sol +1 -0
  42. package/src/structs/JBRulesetMetadata.sol +1 -0
  43. package/src/structs/JBRulesetWeightCache.sol +1 -0
  44. package/src/structs/JBRulesetWithMetadata.sol +1 -0
  45. package/src/structs/JBSingleAllowance.sol +1 -0
  46. package/src/structs/JBSplit.sol +1 -0
  47. package/src/structs/JBSplitGroup.sol +1 -0
  48. package/src/structs/JBSplitHookContext.sol +1 -0
  49. package/src/structs/JBTerminalConfig.sol +1 -0
  50. package/src/structs/JBTokenAmount.sol +1 -0
  51. package/test/ComprehensiveInvariant.t.sol +15 -5
  52. package/test/{AuditExploits.t.sol → CoreExploitTests.t.sol} +35 -4
  53. package/test/EconomicSimulation.t.sol +10 -2
  54. package/test/EntryPointPermutations.t.sol +18 -5
  55. package/test/FlashLoanAttacks.t.sol +12 -2
  56. package/test/PermissionEscalation.t.sol +54 -22
  57. package/test/RulesetTransitions.t.sol +15 -1
  58. package/test/SplitLoopTests.t.sol +26 -5
  59. package/test/TestAccessToFunds.sol +17 -2
  60. package/test/TestCashOut.sol +15 -2
  61. package/test/TestCashOutCountFor.sol +1 -2
  62. package/test/TestCashOutHooks.sol +47 -25
  63. package/test/TestCashOutTimingEdge.sol +13 -1
  64. package/test/TestDurationUnderflow.sol +13 -1
  65. package/test/TestFeeProcessingFailure.sol +17 -7
  66. package/test/TestFees.sol +14 -1
  67. package/test/TestInterfaceSupport.sol +20 -1
  68. package/test/TestJBERC20Inheritance.sol +11 -1
  69. package/test/TestLaunchProject.sol +13 -1
  70. package/test/TestMetaTx.sol +15 -1
  71. package/test/TestMetadataParserLib.sol +37 -4
  72. package/test/TestMigrationHeldFees.sol +17 -11
  73. package/test/TestMintTokensOf.sol +14 -1
  74. package/test/TestMultiTokenSurplus.sol +14 -1
  75. package/test/TestMultipleAccessLimits.sol +23 -1
  76. package/test/TestPayBurnRedeemFlow.sol +16 -1
  77. package/test/TestPayHooks.sol +33 -14
  78. package/test/TestPermissions.sol +20 -1
  79. package/test/TestPermissionsEdge.sol +5 -1
  80. package/test/TestPermit2Terminal.sol +36 -3
  81. package/test/TestRulesetQueueing.sol +24 -1
  82. package/test/TestRulesetQueuingStress.sol +28 -2
  83. package/test/TestRulesetWeightCaching.sol +5 -2
  84. package/test/TestSplits.sol +23 -1
  85. package/test/TestTerminalMigration.sol +11 -1
  86. package/test/TestTokenFlow.sol +18 -1
  87. package/test/TestWeightCacheStaleAfterRejection.sol +15 -1
  88. package/test/WeirdTokenTests.t.sol +18 -2
  89. package/test/fork/TestChainlinkPriceFeedFork.sol +254 -0
  90. package/test/formal/BondingCurveProperties.t.sol +8 -2
  91. package/test/formal/FeeProperties.t.sol +7 -1
  92. package/test/helpers/JBTest.sol +7 -7
  93. package/test/helpers/TestBaseWorkflow.sol +84 -1
  94. package/test/invariants/Phase3DeepInvariant.t.sol +13 -5
  95. package/test/invariants/RulesetsInvariant.t.sol +12 -2
  96. package/test/invariants/TerminalStoreInvariant.t.sol +11 -2
  97. package/test/invariants/TokensInvariant.t.sol +13 -2
  98. package/test/invariants/handlers/ComprehensiveHandler.sol +19 -1
  99. package/test/invariants/handlers/EconomicHandler.sol +31 -1
  100. package/test/invariants/handlers/Phase3Handler.sol +31 -2
  101. package/test/invariants/handlers/RulesetsHandler.sol +5 -1
  102. package/test/invariants/handlers/TerminalStoreHandler.sol +6 -1
  103. package/test/invariants/handlers/TokensHandler.sol +1 -2
  104. package/test/mock/ERC2771ForwarderMock.sol +1 -1
  105. package/test/mock/MockERC20.sol +1 -3
  106. package/test/mock/MockMaliciousBeneficiary.sol +2 -2
  107. package/test/mock/MockMaliciousSplitHook.sol +2 -1
  108. package/test/mock/MockPriceFeed.sol +1 -1
  109. package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +0 -1
  110. package/test/units/static/JBController/JBControllerSetup.sol +10 -1
  111. package/test/units/static/JBController/TestBurnTokensOf.sol +8 -1
  112. package/test/units/static/JBController/TestClaimTokensFor.sol +4 -1
  113. package/test/units/static/JBController/TestDeployErc20For.sol +7 -1
  114. package/test/units/static/JBController/TestLaunchProjectFor.sol +21 -1
  115. package/test/units/static/JBController/TestLaunchRulesetsFor.sol +21 -1
  116. package/test/units/static/JBController/TestMigrateController.sol +10 -1
  117. package/test/units/static/JBController/TestMintTokensOfUnits.sol +10 -1
  118. package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +4 -1
  119. package/test/units/static/JBController/TestReceiveMigrationFrom.sol +5 -1
  120. package/test/units/static/JBController/TestRulesetViews.sol +7 -1
  121. package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +21 -1
  122. package/test/units/static/JBController/TestSetSplitGroupsOf.sol +6 -1
  123. package/test/units/static/JBController/TestSetTokenFor.sol +13 -1
  124. package/test/units/static/JBController/TestSetUriOf.sol +5 -1
  125. package/test/units/static/JBController/TestTransferCreditsFrom.sol +11 -1
  126. package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +15 -4
  127. package/test/units/static/JBDirectory/JBDirectorySetup.sol +4 -1
  128. package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +5 -1
  129. package/test/units/static/JBDirectory/TestSetControllerOf.sol +11 -1
  130. package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +7 -1
  131. package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +11 -1
  132. package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +10 -1
  133. package/test/units/static/JBERC20/JBERC20Setup.sol +2 -1
  134. package/test/units/static/JBERC20/SigUtils.sol +2 -0
  135. package/test/units/static/JBERC20/TestInitialize.sol +1 -1
  136. package/test/units/static/JBERC20/TestName.sol +1 -1
  137. package/test/units/static/JBERC20/TestNonces.sol +3 -1
  138. package/test/units/static/JBERC20/TestSymbol.sol +1 -1
  139. package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +2 -1
  140. package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +2 -1
  141. package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +1 -1
  142. package/test/units/static/JBFees/TestFeesFuzz.sol +1 -1
  143. package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +0 -1
  144. package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +0 -1
  145. package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +3 -1
  146. package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +4 -1
  147. package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +4 -1
  148. package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +8 -1
  149. package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +8 -1
  150. package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +4 -1
  151. package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +7 -1
  152. package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +1 -1
  153. package/test/units/static/JBMetadataResolver/{TestMetadataResolverM20M21.sol → TestMetadataResolverEdgeCases.sol} +6 -5
  154. package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +2 -1
  155. package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +12 -1
  156. package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +9 -1
  157. package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +18 -2
  158. package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +42 -7
  159. package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +30 -6
  160. package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +18 -2
  161. package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +13 -3
  162. package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +21 -4
  163. package/test/units/static/JBMultiTerminal/TestPay.sol +32 -6
  164. package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +0 -1
  165. package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +15 -1
  166. package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +17 -1
  167. package/test/units/static/JBPermissions/JBPermissionsSetup.sol +2 -1
  168. package/test/units/static/JBPermissions/TestHasPermission.sol +1 -1
  169. package/test/units/static/JBPermissions/TestHasPermissions.sol +1 -1
  170. package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +3 -1
  171. package/test/units/static/JBPrices/JBPricesSetup.sol +6 -1
  172. package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +6 -1
  173. package/test/units/static/JBPrices/TestPricePerUnitOf.sol +4 -1
  174. package/test/units/static/JBPrices/TestPrices.sol +4 -1
  175. package/test/units/static/JBProjects/JBProjectsSetup.sol +2 -1
  176. package/test/units/static/JBProjects/TestCreateFor.sol +3 -1
  177. package/test/units/static/JBProjects/TestInitialProject.sol +2 -1
  178. package/test/units/static/JBProjects/TestInterfaces.sol +0 -1
  179. package/test/units/static/JBProjects/TestSetResolver.sol +2 -1
  180. package/test/units/static/JBProjects/TestTokenUri.sol +3 -1
  181. package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +9 -1
  182. package/test/units/static/JBRulesets/JBRulesetsSetup.sol +3 -1
  183. package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +9 -1
  184. package/test/units/static/JBRulesets/TestCurrentOf.sol +10 -1
  185. package/test/units/static/JBRulesets/TestGetRulesetOf.sol +7 -1
  186. package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +9 -1
  187. package/test/units/static/JBRulesets/TestRulesets.sol +12 -2
  188. package/test/units/static/JBRulesets/TestRulesetsOf.sol +1 -1
  189. package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +10 -1
  190. package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +6 -1
  191. package/test/units/static/JBSplits/JBSplitsSetup.sol +3 -1
  192. package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +8 -1
  193. package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +8 -1
  194. package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +6 -1
  195. package/test/units/static/JBSplits/TestSplitsOf.sol +1 -1
  196. package/test/units/static/JBSplits/TestSplitsPacking.sol +5 -2
  197. package/test/units/static/JBSurplus/TestSurplusFuzz.sol +4 -2
  198. package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +5 -1
  199. package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +14 -1
  200. package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +14 -1
  201. package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +3 -1
  202. package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +20 -1
  203. package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +15 -1
  204. package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +13 -1
  205. package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +8 -1
  206. package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +16 -1
  207. package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +15 -1
  208. package/test/units/static/JBTokens/JBTokensSetup.sol +5 -1
  209. package/test/units/static/JBTokens/TestBurnFrom.sol +4 -1
  210. package/test/units/static/JBTokens/TestClaimTokensFor.sol +4 -1
  211. package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +4 -1
  212. package/test/units/static/JBTokens/TestMintFor.sol +4 -1
  213. package/test/units/static/JBTokens/TestSetTokenFor.sol +4 -1
  214. package/test/units/static/JBTokens/TestTotalBalanceOf.sol +1 -1
  215. package/test/units/static/JBTokens/TestTotalSupplyOf.sol +1 -1
  216. package/test/units/static/JBTokens/TestTransferCreditsFrom.sol +3 -1
@@ -1,15 +1,11 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity 0.8.26;
3
3
 
4
- import "@sphinx-labs/contracts/SphinxPlugin.sol";
5
- import {Script, stdJson, VmSafe} from "forge-std/Script.sol";
4
+ import {Sphinx} from "@sphinx-labs/contracts/contracts/foundry/SphinxPlugin.sol";
5
+ import {Script} from "forge-std/Script.sol";
6
6
  import {CoreDeployment, CoreDeploymentLib} from "./helpers/CoreDeploymentLib.sol";
7
7
 
8
- import {IPermit2} from "@uniswap/permit2/src/interfaces/IPermit2.sol";
9
8
  import {IJBPriceFeed} from "src/interfaces/IJBPriceFeed.sol";
10
- import {JBPermissions} from "src/JBPermissions.sol";
11
- import {JBProjects} from "src/JBProjects.sol";
12
- import {JBPrices} from "src/JBPrices.sol";
13
9
  import {JBDeadline3Hours} from "src/periphery/JBDeadline3Hours.sol";
14
10
  import {JBDeadline1Day} from "src/periphery/JBDeadline1Day.sol";
15
11
  import {JBDeadline3Days} from "src/periphery/JBDeadline3Days.sol";
@@ -18,16 +14,7 @@ import {JBMatchingPriceFeed} from "src/periphery/JBMatchingPriceFeed.sol";
18
14
  import {JBChainlinkV3PriceFeed, AggregatorV3Interface} from "src/JBChainlinkV3PriceFeed.sol";
19
15
  import {AggregatorV2V3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV2V3Interface.sol";
20
16
  import {JBChainlinkV3SequencerPriceFeed} from "src/JBChainlinkV3SequencerPriceFeed.sol";
21
- import {JBRulesets} from "src/JBRulesets.sol";
22
- import {JBDirectory} from "src/JBDirectory.sol";
23
- import {JBERC20} from "src/JBERC20.sol";
24
- import {JBTokens} from "src/JBTokens.sol";
25
- import {JBSplits} from "src/JBSplits.sol";
26
- import {JBFeelessAddresses} from "src/JBFeelessAddresses.sol";
27
- import {JBFundAccessLimits} from "src/JBFundAccessLimits.sol";
28
17
  import {JBController} from "src/JBController.sol";
29
- import {JBTerminalStore} from "src/JBTerminalStore.sol";
30
- import {JBMultiTerminal} from "src/JBMultiTerminal.sol";
31
18
 
32
19
  import {JBConstants} from "src/libraries/JBConstants.sol";
33
20
  import {JBCurrencyIds} from "src/libraries/JBCurrencyIds.sol";
@@ -36,13 +23,17 @@ contract DeployPeriphery is Script, Sphinx {
36
23
  /// @notice tracks the deployment of the core contracts for the chain we are deploying to.
37
24
  CoreDeployment core;
38
25
 
26
+ // forge-lint: disable-next-line(mixed-case-variable)
39
27
  address private TRUSTED_FORWARDER;
40
28
 
29
+ // forge-lint: disable-next-line(mixed-case-variable)
41
30
  bytes32 private DEADLINES_SALT = keccak256("_JBDeadlinesV6_");
31
+ // forge-lint: disable-next-line(mixed-case-variable)
42
32
  bytes32 private USD_NATIVE_FEED_SALT = keccak256("USD_FEEDV6");
43
33
 
44
34
  /// @notice The nonce that gets used across all chains to sync deployment addresses and allow for new deployments of
45
35
  /// the same bytecode.
36
+ // forge-lint: disable-next-line(mixed-case-variable)
46
37
  uint256 private CORE_DEPLOYMENT_NONCE = 6;
47
38
 
48
39
  /// @notice The address of the omnichain ruleset operator contract (e.g. JBOmnichainDeployer).
@@ -52,6 +43,7 @@ contract DeployPeriphery is Script, Sphinx {
52
43
  /// @dev This address should correspond to the deterministic CREATE2 deployment of the omnichain deployer contract
53
44
  /// from the nana-omnichain-deployers-v6 repository. Verify it matches the deployed address on all target chains
54
45
  /// before running this script.
46
+ // forge-lint: disable-next-line(mixed-case-variable)
55
47
  address private OMNICHAIN_RULESET_OPERATOR = address(0x8f5DED85c40b50d223269C1F922A056E72101590);
56
48
 
57
49
  function configureSphinx() public override {
@@ -84,6 +76,7 @@ contract DeployPeriphery is Script, Sphinx {
84
76
  matchingPriceFeed = new JBMatchingPriceFeed();
85
77
 
86
78
  // Same as the chainlink example grace period.
79
+ // forge-lint: disable-next-line(mixed-case-variable)
87
80
  uint256 L2GracePeriod = 3600 seconds;
88
81
 
89
82
  // NOTE: Feeds come from this url `https://data.chain.link/feeds/ethereum/mainnet/eth-usd`.
@@ -91,13 +84,15 @@ contract DeployPeriphery is Script, Sphinx {
91
84
 
92
85
  // Perform the deploy for L1(s).
93
86
  if (block.chainid == 1) {
94
- feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}(
95
- AggregatorV3Interface(address(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419)), 3600 seconds
96
- );
87
+ feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}({
88
+ feed: AggregatorV3Interface(address(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419)),
89
+ threshold: 3600 seconds
90
+ });
97
91
  } else if (block.chainid == 11_155_111) {
98
- feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}(
99
- AggregatorV3Interface(address(0x694AA1769357215DE4FAC081bf1f309aDC325306)), 3600 seconds
100
- );
92
+ feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}({
93
+ feed: AggregatorV3Interface(address(0x694AA1769357215DE4FAC081bf1f309aDC325306)),
94
+ threshold: 3600 seconds
95
+ });
101
96
  } else {
102
97
  // Perform the deploy for L2s
103
98
  AggregatorV3Interface source;
@@ -105,47 +100,47 @@ contract DeployPeriphery is Script, Sphinx {
105
100
  // Optimism
106
101
  if (block.chainid == 10) {
107
102
  source = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);
108
- feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}(
109
- source,
110
- 3600 seconds,
111
- AggregatorV2V3Interface(0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389),
112
- L2GracePeriod
113
- );
103
+ feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}({
104
+ feed: source,
105
+ threshold: 3600 seconds,
106
+ sequencerFeed: AggregatorV2V3Interface(0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389),
107
+ gracePeriod: L2GracePeriod
108
+ });
114
109
  }
115
110
  // Optimism Sepolia
116
111
  else if (block.chainid == 11_155_420) {
117
112
  source = AggregatorV3Interface(address(0x61Ec26aA57019C486B10502285c5A3D4A4750AD7));
118
- feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}(source, 3600 seconds);
113
+ feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}({feed: source, threshold: 3600 seconds});
119
114
  }
120
115
  // Base
121
116
  else if (block.chainid == 8453) {
122
117
  source = AggregatorV3Interface(0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70);
123
- feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}(
124
- source,
125
- 3600 seconds,
126
- AggregatorV2V3Interface(0xBCF85224fc0756B9Fa45aA7892530B47e10b6433),
127
- L2GracePeriod
128
- );
118
+ feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}({
119
+ feed: source,
120
+ threshold: 3600 seconds,
121
+ sequencerFeed: AggregatorV2V3Interface(0xBCF85224fc0756B9Fa45aA7892530B47e10b6433),
122
+ gracePeriod: L2GracePeriod
123
+ });
129
124
  }
130
125
  // Base Sepolia
131
126
  else if (block.chainid == 84_532) {
132
127
  source = AggregatorV3Interface(address(0x4aDC67696bA383F43DD60A9e78F2C97Fbbfc7cb1));
133
- feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}(source, 3600 seconds);
128
+ feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}({feed: source, threshold: 3600 seconds});
134
129
  }
135
130
  // Arbitrum
136
131
  else if (block.chainid == 42_161) {
137
132
  source = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);
138
- feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}(
139
- source,
140
- 3600 seconds,
141
- AggregatorV2V3Interface(0xFdB631F5EE196F0ed6FAa767959853A9F217697D),
142
- L2GracePeriod
143
- );
133
+ feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}({
134
+ feed: source,
135
+ threshold: 3600 seconds,
136
+ sequencerFeed: AggregatorV2V3Interface(0xFdB631F5EE196F0ed6FAa767959853A9F217697D),
137
+ gracePeriod: L2GracePeriod
138
+ });
144
139
  }
145
140
  // Arbitrum Sepolia
146
141
  else if (block.chainid == 421_614) {
147
142
  source = AggregatorV3Interface(address(0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165));
148
- feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}(source, 3600 seconds);
143
+ feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}({feed: source, threshold: 3600 seconds});
149
144
  } else {
150
145
  revert("Unsupported chain");
151
146
  }
@@ -182,25 +177,25 @@ contract DeployPeriphery is Script, Sphinx {
182
177
  _deployUSDCFeed(L2GracePeriod);
183
178
 
184
179
  // Deploy the JBDeadlines
185
- if (!_isDeployed(DEADLINES_SALT, type(JBDeadline3Hours).creationCode, "")) {
180
+ if (!_isDeployed({salt: DEADLINES_SALT, creationCode: type(JBDeadline3Hours).creationCode, arguments: ""})) {
186
181
  new JBDeadline3Hours{salt: DEADLINES_SALT}();
187
182
  }
188
183
 
189
- if (!_isDeployed(DEADLINES_SALT, type(JBDeadline1Day).creationCode, "")) {
184
+ if (!_isDeployed({salt: DEADLINES_SALT, creationCode: type(JBDeadline1Day).creationCode, arguments: ""})) {
190
185
  new JBDeadline1Day{salt: DEADLINES_SALT}();
191
186
  }
192
187
 
193
- if (!_isDeployed(DEADLINES_SALT, type(JBDeadline3Days).creationCode, "")) {
188
+ if (!_isDeployed({salt: DEADLINES_SALT, creationCode: type(JBDeadline3Days).creationCode, arguments: ""})) {
194
189
  new JBDeadline3Days{salt: DEADLINES_SALT}();
195
190
  }
196
191
 
197
- if (!_isDeployed(DEADLINES_SALT, type(JBDeadline7Days).creationCode, "")) {
192
+ if (!_isDeployed({salt: DEADLINES_SALT, creationCode: type(JBDeadline7Days).creationCode, arguments: ""})) {
198
193
  new JBDeadline7Days{salt: DEADLINES_SALT}();
199
194
  }
200
195
 
201
196
  core.directory
202
- .setIsAllowedToSetFirstController(
203
- address(
197
+ .setIsAllowedToSetFirstController({
198
+ addr: address(
204
199
  new JBController{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}({
205
200
  directory: core.directory,
206
201
  fundAccessLimits: core.fundAccess,
@@ -214,24 +209,27 @@ contract DeployPeriphery is Script, Sphinx {
214
209
  trustedForwarder: TRUSTED_FORWARDER
215
210
  })
216
211
  ),
217
- true
218
- );
212
+ flag: true
213
+ });
219
214
  }
220
215
 
216
+ // forge-lint: disable-next-line(mixed-case-function, mixed-case-variable)
221
217
  function _deployUSDCFeed(uint256 L2GracePeriod) internal {
222
218
  IJBPriceFeed usdcFeed;
223
219
  address usdc;
224
220
 
225
221
  if (block.chainid == 1) {
226
222
  usdc = address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
227
- usdcFeed = new JBChainlinkV3PriceFeed(
228
- AggregatorV3Interface(address(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6)), 86_400 seconds
229
- );
223
+ usdcFeed = new JBChainlinkV3PriceFeed({
224
+ feed: AggregatorV3Interface(address(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6)),
225
+ threshold: 86_400 seconds
226
+ });
230
227
  } else if (block.chainid == 11_155_111) {
231
228
  usdc = address(0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238);
232
- usdcFeed = new JBChainlinkV3PriceFeed(
233
- AggregatorV3Interface(address(0xA2F78ab2355fe2f984D808B5CeE7FD0A93D5270E)), 86_400 seconds
234
- );
229
+ usdcFeed = new JBChainlinkV3PriceFeed({
230
+ feed: AggregatorV3Interface(address(0xA2F78ab2355fe2f984D808B5CeE7FD0A93D5270E)),
231
+ threshold: 86_400 seconds
232
+ });
235
233
  } else if (block.chainid == 10) {
236
234
  usdc = address(0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85);
237
235
  usdcFeed = new JBChainlinkV3SequencerPriceFeed({
@@ -242,9 +240,10 @@ contract DeployPeriphery is Script, Sphinx {
242
240
  });
243
241
  } else if (block.chainid == 11_155_420) {
244
242
  usdc = address(0x5fd84259d66Cd46123540766Be93DFE6D43130D7);
245
- usdcFeed = new JBChainlinkV3PriceFeed(
246
- AggregatorV3Interface(address(0x6e44e50E3cc14DD16e01C590DC1d7020cb36eD4C)), 86_400 seconds
247
- );
243
+ usdcFeed = new JBChainlinkV3PriceFeed({
244
+ feed: AggregatorV3Interface(address(0x6e44e50E3cc14DD16e01C590DC1d7020cb36eD4C)),
245
+ threshold: 86_400 seconds
246
+ });
248
247
  } else if (block.chainid == 8453) {
249
248
  usdc = address(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913);
250
249
  usdcFeed = new JBChainlinkV3SequencerPriceFeed({
@@ -255,9 +254,10 @@ contract DeployPeriphery is Script, Sphinx {
255
254
  });
256
255
  } else if (block.chainid == 84_532) {
257
256
  usdc = address(0x036CbD53842c5426634e7929541eC2318f3dCF7e);
258
- usdcFeed = new JBChainlinkV3PriceFeed(
259
- AggregatorV3Interface(address(0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165)), 86_400 seconds
260
- );
257
+ usdcFeed = new JBChainlinkV3PriceFeed({
258
+ feed: AggregatorV3Interface(address(0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165)),
259
+ threshold: 86_400 seconds
260
+ });
261
261
  } else if (block.chainid == 42_161) {
262
262
  usdc = address(0xaf88d065e77c8cC2239327C5EDb3A432268e5831);
263
263
  usdcFeed = new JBChainlinkV3SequencerPriceFeed({
@@ -268,9 +268,10 @@ contract DeployPeriphery is Script, Sphinx {
268
268
  });
269
269
  } else if (block.chainid == 421_614) {
270
270
  usdc = address(0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d);
271
- usdcFeed = new JBChainlinkV3PriceFeed(
272
- AggregatorV3Interface(address(0x0153002d20B96532C639313c2d54c3dA09109309)), 86_400 seconds
273
- );
271
+ usdcFeed = new JBChainlinkV3PriceFeed({
272
+ feed: AggregatorV3Interface(address(0x0153002d20B96532C639313c2d54c3dA09109309)),
273
+ threshold: 86_400 seconds
274
+ });
274
275
  } else {
275
276
  revert("Unsupported chain for USDC feed");
276
277
  }
@@ -280,7 +281,11 @@ contract DeployPeriphery is Script, Sphinx {
280
281
 
281
282
  core.prices
282
283
  .addPriceFeedFor({
283
- projectId: 0, pricingCurrency: JBCurrencyIds.USD, unitCurrency: uint32(uint160(usdc)), feed: usdcFeed
284
+ // forge-lint: disable-next-line(unsafe-typecast)
285
+ projectId: 0,
286
+ pricingCurrency: JBCurrencyIds.USD,
287
+ unitCurrency: uint32(uint160(usdc)),
288
+ feed: usdcFeed
284
289
  });
285
290
  }
286
291
 
@@ -16,9 +16,8 @@ import {JBFundAccessLimits} from "../../src/JBFundAccessLimits.sol";
16
16
  import {JBController} from "../../src/JBController.sol";
17
17
  import {JBTerminalStore} from "../../src/JBTerminalStore.sol";
18
18
  import {JBMultiTerminal} from "../../src/JBMultiTerminal.sol";
19
- import {ERC2771Forwarder} from "@openzeppelin/contracts/metatx/ERC2771Forwarder.sol";
20
19
 
21
- import {SphinxConstants, NetworkInfo} from "@sphinx-labs/contracts/SphinxConstants.sol";
20
+ import {SphinxConstants, NetworkInfo} from "@sphinx-labs/contracts/contracts/foundry/SphinxConstants.sol";
22
21
 
23
22
  struct CoreDeployment {
24
23
  JBPermissions permissions;
@@ -39,6 +38,7 @@ struct CoreDeployment {
39
38
  library CoreDeploymentLib {
40
39
  // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.
41
40
  address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code"))));
41
+ // forge-lint: disable-next-line(screaming-snake-case-const)
42
42
  Vm internal constant vm = Vm(VM_ADDRESS);
43
43
  string constant PROJECT_NAME = "nana-core-v5";
44
44
 
@@ -53,7 +53,7 @@ library CoreDeploymentLib {
53
53
 
54
54
  for (uint256 _i; _i < networks.length; _i++) {
55
55
  if (networks[_i].chainId == chainId) {
56
- return getDeployment(path, networks[_i].name);
56
+ return getDeployment({path: path, networkName: networks[_i].name});
57
57
  }
58
58
  }
59
59
 
@@ -62,41 +62,87 @@ library CoreDeploymentLib {
62
62
 
63
63
  function getDeployment(
64
64
  string memory path,
65
- string memory network_name
65
+ string memory networkName
66
66
  )
67
67
  internal
68
68
  view
69
69
  returns (CoreDeployment memory deployment)
70
70
  {
71
- deployment.permissions = JBPermissions(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBPermissions"));
72
-
73
- deployment.projects = JBProjects(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBProjects"));
74
-
75
- deployment.directory = JBDirectory(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBDirectory"));
76
-
77
- deployment.splits = JBSplits(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBSplits"));
78
-
79
- deployment.rulesets = JBRulesets(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBRulesets"));
80
-
81
- deployment.controller = JBController(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBController"));
82
-
83
- deployment.terminal =
84
- JBMultiTerminal(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBMultiTerminal"));
85
-
86
- deployment.terminalStore =
87
- JBTerminalStore(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBTerminalStore"));
88
-
89
- deployment.prices = JBPrices(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBPrices"));
90
-
91
- deployment.feeless =
92
- JBFeelessAddresses(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBFeelessAddresses"));
93
-
94
- deployment.fundAccess =
95
- JBFundAccessLimits(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBFundAccessLimits"));
96
-
97
- deployment.tokens = JBTokens(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBTokens"));
98
-
99
- deployment.trustedForwarder = _getDeploymentAddress(path, PROJECT_NAME, network_name, "ERC2771Forwarder");
71
+ deployment.permissions = JBPermissions(
72
+ _getDeploymentAddress({
73
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBPermissions"
74
+ })
75
+ );
76
+
77
+ deployment.projects = JBProjects(
78
+ _getDeploymentAddress({
79
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBProjects"
80
+ })
81
+ );
82
+
83
+ deployment.directory = JBDirectory(
84
+ _getDeploymentAddress({
85
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBDirectory"
86
+ })
87
+ );
88
+
89
+ deployment.splits = JBSplits(
90
+ _getDeploymentAddress({
91
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBSplits"
92
+ })
93
+ );
94
+
95
+ deployment.rulesets = JBRulesets(
96
+ _getDeploymentAddress({
97
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBRulesets"
98
+ })
99
+ );
100
+
101
+ deployment.controller = JBController(
102
+ _getDeploymentAddress({
103
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBController"
104
+ })
105
+ );
106
+
107
+ deployment.terminal = JBMultiTerminal(
108
+ _getDeploymentAddress({
109
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBMultiTerminal"
110
+ })
111
+ );
112
+
113
+ deployment.terminalStore = JBTerminalStore(
114
+ _getDeploymentAddress({
115
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBTerminalStore"
116
+ })
117
+ );
118
+
119
+ deployment.prices = JBPrices(
120
+ _getDeploymentAddress({
121
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBPrices"
122
+ })
123
+ );
124
+
125
+ deployment.feeless = JBFeelessAddresses(
126
+ _getDeploymentAddress({
127
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBFeelessAddresses"
128
+ })
129
+ );
130
+
131
+ deployment.fundAccess = JBFundAccessLimits(
132
+ _getDeploymentAddress({
133
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBFundAccessLimits"
134
+ })
135
+ );
136
+
137
+ deployment.tokens = JBTokens(
138
+ _getDeploymentAddress({
139
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "JBTokens"
140
+ })
141
+ );
142
+
143
+ deployment.trustedForwarder = _getDeploymentAddress({
144
+ path: path, projectName: PROJECT_NAME, networkName: networkName, contractName: "ERC2771Forwarder"
145
+ });
100
146
  }
101
147
 
102
148
  /// @notice Get the address of a contract that was deployed by the Deploy script.
@@ -106,8 +152,8 @@ library CoreDeploymentLib {
106
152
  /// @return The address of the contract.
107
153
  function _getDeploymentAddress(
108
154
  string memory path,
109
- string memory project_name,
110
- string memory network_name,
155
+ string memory projectName,
156
+ string memory networkName,
111
157
  string memory contractName
112
158
  )
113
159
  internal
@@ -115,7 +161,8 @@ library CoreDeploymentLib {
115
161
  returns (address)
116
162
  {
117
163
  string memory deploymentJson =
118
- vm.readFile(string.concat(path, project_name, "/", network_name, "/", contractName, ".json"));
119
- return stdJson.readAddress(deploymentJson, ".address");
164
+ // forge-lint: disable-next-line(unsafe-cheatcode)
165
+ vm.readFile(string.concat(path, projectName, "/", networkName, "/", contractName, ".json"));
166
+ return stdJson.readAddress({json: deploymentJson, key: ".address"});
120
167
  }
121
168
  }
@@ -68,6 +68,7 @@ contract JBChainlinkV3PriceFeed is IJBPriceFeed {
68
68
  uint256 feedDecimals = FEED.decimals();
69
69
 
70
70
  // Return the price, adjusted to the specified number of decimals.
71
+ // forge-lint: disable-next-line(unsafe-typecast)
71
72
  return uint256(price).adjustDecimals({decimals: feedDecimals, targetDecimals: decimals});
72
73
  }
73
74
  }
@@ -187,7 +187,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
187
187
  /// @dev Can only be called by the directory.
188
188
  /// @param from The controller being migrated from.
189
189
  /// @param projectId The ID of the project that migrated to this controller.
190
- function afterReceiveMigrationFrom(IERC165 from, uint256 projectId) external override {
190
+ function afterReceiveMigrationFrom(IERC165 from, uint256 projectId) external view override {
191
191
  from; // Suppress unused variable warning.
192
192
  projectId; // Suppress unused variable warning.
193
193
 
@@ -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
  //*********************************************************************//