@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
package/ADMINISTRATION.md CHANGED
@@ -108,6 +108,7 @@ Admin privileges and their scope in nana-core-v6.
108
108
  | `sendReservedTokensToSplitsOf` | Anyone | N/A | Per project | Distributes accumulated reserved tokens to the project's reserved token split group. No permission required -- anyone can trigger this. |
109
109
  | `setSplitGroupsOf` | Project owner or operator | SET_SPLIT_GROUPS (18) | Per project | Sets split groups for a project. Must preserve any currently locked splits. |
110
110
  | `setTokenFor` | Project owner or operator | SET_TOKEN (9) | Per project | Assigns an external ERC-20 token to the project. Requires the ruleset's `allowSetCustomToken` flag. Can only be called once (before any token is set). |
111
+ | `setTokenMetadataOf` | Project owner or operator | SET_TOKEN_METADATA (21) | Per project | Sets the name and symbol of a project's ERC-20 token. The project must have a token deployed. |
111
112
  | `setUriOf` | Project owner or operator | SET_PROJECT_URI (7) | Per project | Updates the project's metadata URI. |
112
113
  | `transferCreditsFrom` | Credit holder or operator | TRANSFER_CREDITS (13) | Per project | Transfers internal token credits between addresses. Requires the ruleset's `pauseCreditTransfers` flag to be false. |
113
114
  | `migrate` | JBDirectory only | N/A (msg.sender == DIRECTORY) | Per project | Called by the directory during controller migration. Reverts if there are pending reserved tokens. |
@@ -140,6 +141,7 @@ Admin privileges and their scope in nana-core-v6.
140
141
  | `deployERC20For` | Project's controller | N/A (onlyControllerOf) | Per project | Deploys a cloned JBERC20 token for the project. |
141
142
  | `mintFor` | Project's controller | N/A (onlyControllerOf) | Per project | Mints new tokens (ERC-20 if deployed) or credits for a holder. |
142
143
  | `setTokenFor` | Project's controller | N/A (onlyControllerOf) | Per project | Sets an external ERC-20 token for the project. Cannot be changed once set. |
144
+ | `setTokenMetadataFor` | Project's controller | N/A (onlyControllerOf) | Per project | Sets the name and symbol of a project's token. |
143
145
  | `transferCreditsFrom` | Project's controller | N/A (onlyControllerOf) | Per project | Transfers credits between addresses. |
144
146
 
145
147
  ### JBSplits
@@ -180,6 +182,7 @@ Admin privileges and their scope in nana-core-v6.
180
182
  | `mint` | Contract owner (JBTokens) | N/A (onlyOwner) | Per token | Mints new tokens to an address. |
181
183
  | `burn` | Contract owner (JBTokens) | N/A (onlyOwner) | Per token | Burns tokens from an address. |
182
184
  | `initialize` | Anyone (once) | N/A | Per token | Initializes the token name, symbol, and owner. Can only be called once. |
185
+ | `setMetadata` | Contract owner (JBTokens) | N/A (onlyOwner) | Per token | Updates the token's name and symbol. |
183
186
 
184
187
  ### JBTerminalStore
185
188
 
@@ -228,6 +231,7 @@ JBPermissions implements a 256-bit packed permission bitmap system:
228
231
  | 18 | SET_SPLIT_GROUPS | `JBController.setSplitGroupsOf` |
229
232
  | 19 | ADD_PRICE_FEED | `JBController.addPriceFeed` |
230
233
  | 20 | ADD_ACCOUNTING_CONTEXTS | `JBMultiTerminal.addAccountingContextsFor` |
234
+ | 21 | SET_TOKEN_METADATA | `JBController.setTokenMetadataOf` |
231
235
 
232
236
  ## Immutable Configuration
233
237
 
package/README.md CHANGED
@@ -97,7 +97,7 @@ All contracts use Solidity `0.8.26`.
97
97
  | `JBProjects` | ERC-721 registry of projects. Minting an NFT creates a project. Optionally mints project #1 to a fee beneficiary owner. |
98
98
  | `JBPermissions` | Bitmap-based permission system. Accounts grant operators specific permissions scoped to project IDs. Supports ROOT (255) for all-permissions and wildcard project ID (0). |
99
99
  | `JBDirectory` | Maps each project to its controller and terminals. Entry point for looking up where to interact with a project. Manages an allowlist of addresses permitted to set a project's first controller. |
100
- | `JBController` | Coordinates rulesets, tokens, splits, and fund access limits. Entry point for launching projects, queuing rulesets, minting/burning tokens, deploying ERC-20s, sending reserved tokens, setting project URIs, adding price feeds, and transferring credits. |
100
+ | `JBController` | Coordinates rulesets, tokens, splits, and fund access limits. Entry point for launching projects, queuing rulesets, minting/burning tokens, deploying ERC-20s, updating token metadata, sending reserved tokens, setting project URIs, adding price feeds, and transferring credits. |
101
101
  | `JBMultiTerminal` | Accepts payments (native ETH and ERC-20s), processes cash outs, distributes payouts, manages surplus allowances, and handles fees. Integrates with Permit2 for ERC-20 approvals. |
102
102
  | `JBTerminalStore` | Bookkeeping engine for all terminal inflows and outflows. Tracks balances, enforces payout limits and surplus allowances, computes cash out reclaim amounts via a bonding curve, and integrates with data hooks. |
103
103
  | `JBRulesets` | Stores and manages project rulesets. Handles queuing, cycling, weight decay, approval hook validation, and weight caching for long-running projects. |
@@ -110,7 +110,7 @@ All contracts use Solidity `0.8.26`.
110
110
 
111
111
  | Contract | Description |
112
112
  |----------|-------------|
113
- | `JBERC20` | Cloneable ERC-20 with ERC20Votes and ERC20Permit. Deployed by `JBTokens` via `Clones.clone()`. Owned by `JBTokens`. |
113
+ | `JBERC20` | Cloneable ERC-20 with ERC20Votes and ERC20Permit. Deployed by `JBTokens` via `Clones.clone()`. Owned by `JBTokens`. Name and symbol can be updated by the project owner via `JBController.setTokenMetadataOf`. |
114
114
  | `JBChainlinkV3PriceFeed` | `IJBPriceFeed` backed by a Chainlink `AggregatorV3Interface` with staleness threshold. Rejects negative/zero prices and incomplete rounds. |
115
115
  | `JBChainlinkV3SequencerPriceFeed` | Extends `JBChainlinkV3PriceFeed` with L2 sequencer uptime validation and grace period for Optimism/Arbitrum. |
116
116
  | `JBMatchingPriceFeed` | Returns 1:1 price (e.g., ETH/NATIVE_TOKEN on applicable chains). Lives in `src/periphery/`. |
package/SKILLS.md CHANGED
@@ -42,6 +42,7 @@ The core Juicebox V6 protocol on EVM: a modular system for launching treasury-ba
42
42
  | `claimTokensFor(address holder, uint256 projectId, uint256 count, address beneficiary)` | Redeems credits for ERC-20 tokens into beneficiary's wallet. |
43
43
  | `setSplitGroupsOf(uint256 projectId, uint256 rulesetId, JBSplitGroup[] splitGroups)` | Sets the split groups for a project's ruleset. |
44
44
  | `setTokenFor(uint256 projectId, IJBToken token)` | Sets an existing ERC-20 token for the project (requires `allowSetCustomToken` in ruleset). |
45
+ | `setTokenMetadataOf(uint256 projectId, string name, string symbol)` | Sets the name and symbol of a project's ERC-20 token. Requires `SET_TOKEN_METADATA` permission. |
45
46
  | `setUriOf(uint256 projectId, string uri)` | Sets the project's metadata URI. |
46
47
  | `transferCreditsFrom(address holder, uint256 projectId, address recipient, uint256 creditCount)` | Transfers credits between addresses (reverts if `pauseCreditTransfers` is set in ruleset). |
47
48
  | `addPriceFeedFor(uint256 projectId, uint256 pricingCurrency, uint256 unitCurrency, IJBPriceFeed feed)` | Registers a price feed (requires `allowAddPriceFeed` in ruleset). |
@@ -129,6 +130,7 @@ The core Juicebox V6 protocol on EVM: a modular system for launching treasury-ba
129
130
  | `totalBalanceOf(address holder, uint256 projectId)` | Returns combined credit + ERC-20 balance. |
130
131
  | `creditBalanceOf(address holder, uint256 projectId)` | Returns the holder's credit balance. |
131
132
  | `tokenOf(uint256 projectId)` | Returns the ERC-20 token for a project (`IJBToken`). |
133
+ | `setTokenMetadataFor(uint256 projectId, string name, string symbol)` | Sets the name and symbol of a project's token. Controller-only. |
132
134
 
133
135
  ### JBSplits
134
136
 
package/STYLE_GUIDE.md CHANGED
@@ -197,7 +197,7 @@ interface IJBExample is IJBBase {
197
197
  | Public/external function | `camelCase` | `cashOutTokensOf` |
198
198
  | Internal/private function | `_camelCase` | `_processFee` |
199
199
  | Internal storage | `_camelCase` | `_accountingContextForTokenOf` |
200
- | Function parameter | `camelCase` | `projectId`, `cashOutCount` |
200
+ | Function parameter | `camelCase` (no underscores) | `projectId`, `cashOutCount` |
201
201
 
202
202
  ## NatSpec
203
203
 
@@ -253,9 +253,12 @@ uint256 public constant MAX_RESERVED_PERCENT = 10_000;
253
253
 
254
254
  ## Function Calls
255
255
 
256
- Use named parameters for readability when calling functions with 3+ arguments:
256
+ Use named arguments for all function calls with 2 or more arguments — in both `src/` and `script/`:
257
257
 
258
258
  ```solidity
259
+ // Good — named arguments
260
+ token.mint({account: beneficiary, amount: count});
261
+ _transferOwnership({newOwner: address(0), projectId: 0});
259
262
  PERMISSIONS.hasPermission({
260
263
  operator: sender,
261
264
  account: account,
@@ -264,8 +267,18 @@ PERMISSIONS.hasPermission({
264
267
  includeRoot: true,
265
268
  includeWildcardProjectId: true
266
269
  });
270
+
271
+ // Bad — positional arguments with 2+ args
272
+ token.mint(beneficiary, count);
273
+ _transferOwnership(address(0), 0);
267
274
  ```
268
275
 
276
+ Single-argument calls use positional style: `_burn(amount)`.
277
+
278
+ This also applies to constructor calls, struct literals, and inherited/library calls (e.g., OZ `_mint`, `_safeMint`, `safeTransfer`, `allowance`, `Clones.cloneDeterministic`).
279
+
280
+ Named argument keys must use **camelCase** — never underscores. If a function's parameter names use underscores, rename them to camelCase first.
281
+
269
282
  ## Multiline Signatures
270
283
 
271
284
  ```solidity
@@ -553,6 +566,7 @@ CI checks formatting via `forge fmt --check`.
553
566
 
554
567
  CI runs `forge build --sizes` to catch contracts approaching the 24KB limit. When the repo's default `optimizer_runs` differs from what you want for size checking, use `FOUNDRY_PROFILE=ci_sizes forge build --sizes` with a `[profile.ci_sizes]` section in `foundry.toml`.
555
568
 
569
+
556
570
  ## Repo-Specific Deviations
557
571
 
558
572
  None. This repo follows the standard configuration exactly.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bananapus/core-v6",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  "artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'nana-core-v6'"
27
27
  },
28
28
  "dependencies": {
29
- "@bananapus/permission-ids-v6": "^0.0.8",
29
+ "@bananapus/permission-ids-v6": "^0.0.9",
30
30
  "@chainlink/contracts": "^1.3.0",
31
31
  "@openzeppelin/contracts": "^5.6.1",
32
32
  "@prb/math": "^4.1.1",
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity 0.8.26;
3
3
 
4
- import "@sphinx-labs/contracts/contracts/foundry/SphinxPlugin.sol";
4
+ import {Sphinx} from "@sphinx-labs/contracts/contracts/foundry/SphinxPlugin.sol";
5
5
  import {Script} from "forge-std/Script.sol";
6
6
 
7
7
  import {IPermit2} from "@uniswap/permit2/src/interfaces/IPermit2.sol";
@@ -26,16 +26,20 @@ contract Deploy is Script, Sphinx {
26
26
 
27
27
  /// @notice The address that is allowed to forward calls to the terminal and controller on a users behalf.
28
28
  string private constant TRUSTED_FORWARDER_NAME = "Juicebox";
29
+ // forge-lint: disable-next-line(mixed-case-variable)
29
30
  address private TRUSTED_FORWARDER;
30
31
 
31
32
  /// @notice The address that will manage the few privileged functions of the protocol.
33
+ // forge-lint: disable-next-line(mixed-case-variable)
32
34
  address private MANAGER;
33
35
 
34
36
  /// @notice The address that will own the fee-project.
37
+ // forge-lint: disable-next-line(mixed-case-variable)
35
38
  address private FEE_PROJECT_OWNER;
36
39
 
37
40
  /// @notice The nonce that gets used across all chains to sync deployment addresses and allow for new deployments of
38
41
  /// the same bytecode.
42
+ // forge-lint: disable-next-line(mixed-case-variable)
39
43
  uint256 private CORE_DEPLOYMENT_NONCE = 6;
40
44
 
41
45
  function configureSphinx() public override {
@@ -61,19 +65,24 @@ contract Deploy is Script, Sphinx {
61
65
 
62
66
  JBPermissions permissions =
63
67
  new JBPermissions{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}(TRUSTED_FORWARDER);
64
- JBProjects projects = new JBProjects{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}(
65
- safeAddress(), safeAddress(), TRUSTED_FORWARDER
66
- );
67
- JBDirectory directory =
68
- new JBDirectory{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}(permissions, projects, safeAddress());
68
+ JBProjects projects = new JBProjects{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}({
69
+ owner: safeAddress(), feeProjectOwner: safeAddress(), trustedForwarder: TRUSTED_FORWARDER
70
+ });
71
+ JBDirectory directory = new JBDirectory{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}({
72
+ permissions: permissions, projects: projects, owner: safeAddress()
73
+ });
69
74
  JBSplits splits = new JBSplits{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}(directory);
70
75
  JBRulesets rulesets = new JBRulesets{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}(directory);
71
- JBPrices prices = new JBPrices{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}(
72
- directory, permissions, projects, safeAddress(), TRUSTED_FORWARDER
73
- );
74
- JBTokens tokens = new JBTokens{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}(
75
- directory, new JBERC20{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}()
76
- );
76
+ JBPrices prices = new JBPrices{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}({
77
+ directory: directory,
78
+ permissions: permissions,
79
+ projects: projects,
80
+ owner: safeAddress(),
81
+ trustedForwarder: TRUSTED_FORWARDER
82
+ });
83
+ JBTokens tokens = new JBTokens{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}({
84
+ directory: directory, token: new JBERC20{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}()
85
+ });
77
86
 
78
87
  new JBFundAccessLimits{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}(directory);
79
88
 
@@ -103,7 +112,7 @@ contract Deploy is Script, Sphinx {
103
112
 
104
113
  // Transfer ownership to the fee project owner.
105
114
  if (FEE_PROJECT_OWNER != safeAddress() && FEE_PROJECT_OWNER != address(0)) {
106
- projects.safeTransferFrom(safeAddress(), FEE_PROJECT_OWNER, 1);
115
+ projects.safeTransferFrom({from: safeAddress(), to: FEE_PROJECT_OWNER, tokenId: 1});
107
116
  }
108
117
  }
109
118
  }
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity 0.8.26;
3
3
 
4
- import "@sphinx-labs/contracts/contracts/foundry/SphinxPlugin.sol";
4
+ import {Sphinx} from "@sphinx-labs/contracts/contracts/foundry/SphinxPlugin.sol";
5
5
  import {Script} from "forge-std/Script.sol";
6
6
  import {CoreDeployment, CoreDeploymentLib} from "./helpers/CoreDeploymentLib.sol";
7
7
 
@@ -23,13 +23,17 @@ contract DeployPeriphery is Script, Sphinx {
23
23
  /// @notice tracks the deployment of the core contracts for the chain we are deploying to.
24
24
  CoreDeployment core;
25
25
 
26
+ // forge-lint: disable-next-line(mixed-case-variable)
26
27
  address private TRUSTED_FORWARDER;
27
28
 
29
+ // forge-lint: disable-next-line(mixed-case-variable)
28
30
  bytes32 private DEADLINES_SALT = keccak256("_JBDeadlinesV6_");
31
+ // forge-lint: disable-next-line(mixed-case-variable)
29
32
  bytes32 private USD_NATIVE_FEED_SALT = keccak256("USD_FEEDV6");
30
33
 
31
34
  /// @notice The nonce that gets used across all chains to sync deployment addresses and allow for new deployments of
32
35
  /// the same bytecode.
36
+ // forge-lint: disable-next-line(mixed-case-variable)
33
37
  uint256 private CORE_DEPLOYMENT_NONCE = 6;
34
38
 
35
39
  /// @notice The address of the omnichain ruleset operator contract (e.g. JBOmnichainDeployer).
@@ -39,6 +43,7 @@ contract DeployPeriphery is Script, Sphinx {
39
43
  /// @dev This address should correspond to the deterministic CREATE2 deployment of the omnichain deployer contract
40
44
  /// from the nana-omnichain-deployers-v6 repository. Verify it matches the deployed address on all target chains
41
45
  /// before running this script.
46
+ // forge-lint: disable-next-line(mixed-case-variable)
42
47
  address private OMNICHAIN_RULESET_OPERATOR = address(0x8f5DED85c40b50d223269C1F922A056E72101590);
43
48
 
44
49
  function configureSphinx() public override {
@@ -71,6 +76,7 @@ contract DeployPeriphery is Script, Sphinx {
71
76
  matchingPriceFeed = new JBMatchingPriceFeed();
72
77
 
73
78
  // Same as the chainlink example grace period.
79
+ // forge-lint: disable-next-line(mixed-case-variable)
74
80
  uint256 L2GracePeriod = 3600 seconds;
75
81
 
76
82
  // NOTE: Feeds come from this url `https://data.chain.link/feeds/ethereum/mainnet/eth-usd`.
@@ -78,13 +84,15 @@ contract DeployPeriphery is Script, Sphinx {
78
84
 
79
85
  // Perform the deploy for L1(s).
80
86
  if (block.chainid == 1) {
81
- feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}(
82
- AggregatorV3Interface(address(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419)), 3600 seconds
83
- );
87
+ feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}({
88
+ feed: AggregatorV3Interface(address(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419)),
89
+ threshold: 3600 seconds
90
+ });
84
91
  } else if (block.chainid == 11_155_111) {
85
- feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}(
86
- AggregatorV3Interface(address(0x694AA1769357215DE4FAC081bf1f309aDC325306)), 3600 seconds
87
- );
92
+ feed = new JBChainlinkV3PriceFeed{salt: USD_NATIVE_FEED_SALT}({
93
+ feed: AggregatorV3Interface(address(0x694AA1769357215DE4FAC081bf1f309aDC325306)),
94
+ threshold: 3600 seconds
95
+ });
88
96
  } else {
89
97
  // Perform the deploy for L2s
90
98
  AggregatorV3Interface source;
@@ -92,47 +100,47 @@ contract DeployPeriphery is Script, Sphinx {
92
100
  // Optimism
93
101
  if (block.chainid == 10) {
94
102
  source = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);
95
- feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}(
96
- source,
97
- 3600 seconds,
98
- AggregatorV2V3Interface(0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389),
99
- L2GracePeriod
100
- );
103
+ feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}({
104
+ feed: source,
105
+ threshold: 3600 seconds,
106
+ sequencerFeed: AggregatorV2V3Interface(0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389),
107
+ gracePeriod: L2GracePeriod
108
+ });
101
109
  }
102
110
  // Optimism Sepolia
103
111
  else if (block.chainid == 11_155_420) {
104
112
  source = AggregatorV3Interface(address(0x61Ec26aA57019C486B10502285c5A3D4A4750AD7));
105
- 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});
106
114
  }
107
115
  // Base
108
116
  else if (block.chainid == 8453) {
109
117
  source = AggregatorV3Interface(0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70);
110
- feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}(
111
- source,
112
- 3600 seconds,
113
- AggregatorV2V3Interface(0xBCF85224fc0756B9Fa45aA7892530B47e10b6433),
114
- L2GracePeriod
115
- );
118
+ feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}({
119
+ feed: source,
120
+ threshold: 3600 seconds,
121
+ sequencerFeed: AggregatorV2V3Interface(0xBCF85224fc0756B9Fa45aA7892530B47e10b6433),
122
+ gracePeriod: L2GracePeriod
123
+ });
116
124
  }
117
125
  // Base Sepolia
118
126
  else if (block.chainid == 84_532) {
119
127
  source = AggregatorV3Interface(address(0x4aDC67696bA383F43DD60A9e78F2C97Fbbfc7cb1));
120
- 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});
121
129
  }
122
130
  // Arbitrum
123
131
  else if (block.chainid == 42_161) {
124
132
  source = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);
125
- feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}(
126
- source,
127
- 3600 seconds,
128
- AggregatorV2V3Interface(0xFdB631F5EE196F0ed6FAa767959853A9F217697D),
129
- L2GracePeriod
130
- );
133
+ feed = new JBChainlinkV3SequencerPriceFeed{salt: USD_NATIVE_FEED_SALT}({
134
+ feed: source,
135
+ threshold: 3600 seconds,
136
+ sequencerFeed: AggregatorV2V3Interface(0xFdB631F5EE196F0ed6FAa767959853A9F217697D),
137
+ gracePeriod: L2GracePeriod
138
+ });
131
139
  }
132
140
  // Arbitrum Sepolia
133
141
  else if (block.chainid == 421_614) {
134
142
  source = AggregatorV3Interface(address(0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165));
135
- 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});
136
144
  } else {
137
145
  revert("Unsupported chain");
138
146
  }
@@ -169,25 +177,25 @@ contract DeployPeriphery is Script, Sphinx {
169
177
  _deployUSDCFeed(L2GracePeriod);
170
178
 
171
179
  // Deploy the JBDeadlines
172
- if (!_isDeployed(DEADLINES_SALT, type(JBDeadline3Hours).creationCode, "")) {
180
+ if (!_isDeployed({salt: DEADLINES_SALT, creationCode: type(JBDeadline3Hours).creationCode, arguments: ""})) {
173
181
  new JBDeadline3Hours{salt: DEADLINES_SALT}();
174
182
  }
175
183
 
176
- if (!_isDeployed(DEADLINES_SALT, type(JBDeadline1Day).creationCode, "")) {
184
+ if (!_isDeployed({salt: DEADLINES_SALT, creationCode: type(JBDeadline1Day).creationCode, arguments: ""})) {
177
185
  new JBDeadline1Day{salt: DEADLINES_SALT}();
178
186
  }
179
187
 
180
- if (!_isDeployed(DEADLINES_SALT, type(JBDeadline3Days).creationCode, "")) {
188
+ if (!_isDeployed({salt: DEADLINES_SALT, creationCode: type(JBDeadline3Days).creationCode, arguments: ""})) {
181
189
  new JBDeadline3Days{salt: DEADLINES_SALT}();
182
190
  }
183
191
 
184
- if (!_isDeployed(DEADLINES_SALT, type(JBDeadline7Days).creationCode, "")) {
192
+ if (!_isDeployed({salt: DEADLINES_SALT, creationCode: type(JBDeadline7Days).creationCode, arguments: ""})) {
185
193
  new JBDeadline7Days{salt: DEADLINES_SALT}();
186
194
  }
187
195
 
188
196
  core.directory
189
- .setIsAllowedToSetFirstController(
190
- address(
197
+ .setIsAllowedToSetFirstController({
198
+ addr: address(
191
199
  new JBController{salt: keccak256(abi.encode(CORE_DEPLOYMENT_NONCE))}({
192
200
  directory: core.directory,
193
201
  fundAccessLimits: core.fundAccess,
@@ -201,24 +209,27 @@ contract DeployPeriphery is Script, Sphinx {
201
209
  trustedForwarder: TRUSTED_FORWARDER
202
210
  })
203
211
  ),
204
- true
205
- );
212
+ flag: true
213
+ });
206
214
  }
207
215
 
216
+ // forge-lint: disable-next-line(mixed-case-function, mixed-case-variable)
208
217
  function _deployUSDCFeed(uint256 L2GracePeriod) internal {
209
218
  IJBPriceFeed usdcFeed;
210
219
  address usdc;
211
220
 
212
221
  if (block.chainid == 1) {
213
222
  usdc = address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
214
- usdcFeed = new JBChainlinkV3PriceFeed(
215
- AggregatorV3Interface(address(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6)), 86_400 seconds
216
- );
223
+ usdcFeed = new JBChainlinkV3PriceFeed({
224
+ feed: AggregatorV3Interface(address(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6)),
225
+ threshold: 86_400 seconds
226
+ });
217
227
  } else if (block.chainid == 11_155_111) {
218
228
  usdc = address(0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238);
219
- usdcFeed = new JBChainlinkV3PriceFeed(
220
- AggregatorV3Interface(address(0xA2F78ab2355fe2f984D808B5CeE7FD0A93D5270E)), 86_400 seconds
221
- );
229
+ usdcFeed = new JBChainlinkV3PriceFeed({
230
+ feed: AggregatorV3Interface(address(0xA2F78ab2355fe2f984D808B5CeE7FD0A93D5270E)),
231
+ threshold: 86_400 seconds
232
+ });
222
233
  } else if (block.chainid == 10) {
223
234
  usdc = address(0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85);
224
235
  usdcFeed = new JBChainlinkV3SequencerPriceFeed({
@@ -229,9 +240,10 @@ contract DeployPeriphery is Script, Sphinx {
229
240
  });
230
241
  } else if (block.chainid == 11_155_420) {
231
242
  usdc = address(0x5fd84259d66Cd46123540766Be93DFE6D43130D7);
232
- usdcFeed = new JBChainlinkV3PriceFeed(
233
- AggregatorV3Interface(address(0x6e44e50E3cc14DD16e01C590DC1d7020cb36eD4C)), 86_400 seconds
234
- );
243
+ usdcFeed = new JBChainlinkV3PriceFeed({
244
+ feed: AggregatorV3Interface(address(0x6e44e50E3cc14DD16e01C590DC1d7020cb36eD4C)),
245
+ threshold: 86_400 seconds
246
+ });
235
247
  } else if (block.chainid == 8453) {
236
248
  usdc = address(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913);
237
249
  usdcFeed = new JBChainlinkV3SequencerPriceFeed({
@@ -242,9 +254,10 @@ contract DeployPeriphery is Script, Sphinx {
242
254
  });
243
255
  } else if (block.chainid == 84_532) {
244
256
  usdc = address(0x036CbD53842c5426634e7929541eC2318f3dCF7e);
245
- usdcFeed = new JBChainlinkV3PriceFeed(
246
- AggregatorV3Interface(address(0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165)), 86_400 seconds
247
- );
257
+ usdcFeed = new JBChainlinkV3PriceFeed({
258
+ feed: AggregatorV3Interface(address(0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165)),
259
+ threshold: 86_400 seconds
260
+ });
248
261
  } else if (block.chainid == 42_161) {
249
262
  usdc = address(0xaf88d065e77c8cC2239327C5EDb3A432268e5831);
250
263
  usdcFeed = new JBChainlinkV3SequencerPriceFeed({
@@ -255,9 +268,10 @@ contract DeployPeriphery is Script, Sphinx {
255
268
  });
256
269
  } else if (block.chainid == 421_614) {
257
270
  usdc = address(0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d);
258
- usdcFeed = new JBChainlinkV3PriceFeed(
259
- AggregatorV3Interface(address(0x0153002d20B96532C639313c2d54c3dA09109309)), 86_400 seconds
260
- );
271
+ usdcFeed = new JBChainlinkV3PriceFeed({
272
+ feed: AggregatorV3Interface(address(0x0153002d20B96532C639313c2d54c3dA09109309)),
273
+ threshold: 86_400 seconds
274
+ });
261
275
  } else {
262
276
  revert("Unsupported chain for USDC feed");
263
277
  }
@@ -267,7 +281,11 @@ contract DeployPeriphery is Script, Sphinx {
267
281
 
268
282
  core.prices
269
283
  .addPriceFeedFor({
270
- 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
271
289
  });
272
290
  }
273
291
 
@@ -38,6 +38,7 @@ struct CoreDeployment {
38
38
  library CoreDeploymentLib {
39
39
  // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.
40
40
  address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code"))));
41
+ // forge-lint: disable-next-line(screaming-snake-case-const)
41
42
  Vm internal constant vm = Vm(VM_ADDRESS);
42
43
  string constant PROJECT_NAME = "nana-core-v5";
43
44
 
@@ -52,7 +53,7 @@ library CoreDeploymentLib {
52
53
 
53
54
  for (uint256 _i; _i < networks.length; _i++) {
54
55
  if (networks[_i].chainId == chainId) {
55
- return getDeployment(path, networks[_i].name);
56
+ return getDeployment({path: path, networkName: networks[_i].name});
56
57
  }
57
58
  }
58
59
 
@@ -61,41 +62,87 @@ library CoreDeploymentLib {
61
62
 
62
63
  function getDeployment(
63
64
  string memory path,
64
- string memory network_name
65
+ string memory networkName
65
66
  )
66
67
  internal
67
68
  view
68
69
  returns (CoreDeployment memory deployment)
69
70
  {
70
- deployment.permissions = JBPermissions(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBPermissions"));
71
-
72
- deployment.projects = JBProjects(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBProjects"));
73
-
74
- deployment.directory = JBDirectory(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBDirectory"));
75
-
76
- deployment.splits = JBSplits(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBSplits"));
77
-
78
- deployment.rulesets = JBRulesets(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBRulesets"));
79
-
80
- deployment.controller = JBController(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBController"));
81
-
82
- deployment.terminal =
83
- JBMultiTerminal(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBMultiTerminal"));
84
-
85
- deployment.terminalStore =
86
- JBTerminalStore(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBTerminalStore"));
87
-
88
- deployment.prices = JBPrices(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBPrices"));
89
-
90
- deployment.feeless =
91
- JBFeelessAddresses(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBFeelessAddresses"));
92
-
93
- deployment.fundAccess =
94
- JBFundAccessLimits(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBFundAccessLimits"));
95
-
96
- deployment.tokens = JBTokens(_getDeploymentAddress(path, PROJECT_NAME, network_name, "JBTokens"));
97
-
98
- 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
+ });
99
146
  }
100
147
 
101
148
  /// @notice Get the address of a contract that was deployed by the Deploy script.
@@ -105,8 +152,8 @@ library CoreDeploymentLib {
105
152
  /// @return The address of the contract.
106
153
  function _getDeploymentAddress(
107
154
  string memory path,
108
- string memory project_name,
109
- string memory network_name,
155
+ string memory projectName,
156
+ string memory networkName,
110
157
  string memory contractName
111
158
  )
112
159
  internal
@@ -114,7 +161,8 @@ library CoreDeploymentLib {
114
161
  returns (address)
115
162
  {
116
163
  string memory deploymentJson =
117
- vm.readFile(string.concat(path, project_name, "/", network_name, "/", contractName, ".json"));
118
- 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"});
119
167
  }
120
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
  }