@bananapus/core-v6 0.0.1

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 (436) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +112 -0
  3. package/SKILLS.md +151 -0
  4. package/docs/book.css +13 -0
  5. package/docs/book.toml +12 -0
  6. package/docs/solidity.min.js +74 -0
  7. package/docs/src/README.md +703 -0
  8. package/docs/src/SUMMARY.md +94 -0
  9. package/docs/src/src/JBChainlinkV3PriceFeed.sol/contract.JBChainlinkV3PriceFeed.md +83 -0
  10. package/docs/src/src/JBChainlinkV3SequencerPriceFeed.sol/contract.JBChainlinkV3SequencerPriceFeed.md +88 -0
  11. package/docs/src/src/JBController.sol/contract.JBController.md +1121 -0
  12. package/docs/src/src/JBDeadline.sol/contract.JBDeadline.md +84 -0
  13. package/docs/src/src/JBDirectory.sol/contract.JBDirectory.md +294 -0
  14. package/docs/src/src/JBERC20.sol/contract.JBERC20.md +190 -0
  15. package/docs/src/src/JBFeelessAddresses.sol/contract.JBFeelessAddresses.md +80 -0
  16. package/docs/src/src/JBFundAccessLimits.sol/contract.JBFundAccessLimits.md +253 -0
  17. package/docs/src/src/JBMultiTerminal.sol/contract.JBMultiTerminal.md +1472 -0
  18. package/docs/src/src/JBPermissions.sol/contract.JBPermissions.md +199 -0
  19. package/docs/src/src/JBPrices.sol/contract.JBPrices.md +154 -0
  20. package/docs/src/src/JBProjects.sol/contract.JBProjects.md +131 -0
  21. package/docs/src/src/JBRulesets.sol/contract.JBRulesets.md +677 -0
  22. package/docs/src/src/JBSplits.sol/contract.JBSplits.md +237 -0
  23. package/docs/src/src/JBTerminalStore.sol/contract.JBTerminalStore.md +591 -0
  24. package/docs/src/src/JBTokens.sol/contract.JBTokens.md +353 -0
  25. package/docs/src/src/README.md +25 -0
  26. package/docs/src/src/abstract/JBControlled.sol/abstract.JBControlled.md +64 -0
  27. package/docs/src/src/abstract/JBPermissioned.sol/abstract.JBPermissioned.md +84 -0
  28. package/docs/src/src/abstract/README.md +5 -0
  29. package/docs/src/src/enums/JBApprovalStatus.sol/enum.JBApprovalStatus.md +17 -0
  30. package/docs/src/src/enums/README.md +4 -0
  31. package/docs/src/src/interfaces/IJBCashOutHook.sol/interface.IJBCashOutHook.md +29 -0
  32. package/docs/src/src/interfaces/IJBCashOutTerminal.sol/interface.IJBCashOutTerminal.md +57 -0
  33. package/docs/src/src/interfaces/IJBControlled.sol/interface.IJBControlled.md +12 -0
  34. package/docs/src/src/interfaces/IJBController.sol/interface.IJBController.md +334 -0
  35. package/docs/src/src/interfaces/IJBDirectory.sol/interface.IJBDirectory.md +108 -0
  36. package/docs/src/src/interfaces/IJBDirectoryAccessControl.sol/interface.IJBDirectoryAccessControl.md +19 -0
  37. package/docs/src/src/interfaces/IJBFeeTerminal.sol/interface.IJBFeeTerminal.md +91 -0
  38. package/docs/src/src/interfaces/IJBFeelessAddresses.sol/interface.IJBFeelessAddresses.md +26 -0
  39. package/docs/src/src/interfaces/IJBFundAccessLimits.sol/interface.IJBFundAccessLimits.md +88 -0
  40. package/docs/src/src/interfaces/IJBMigratable.sol/interface.IJBMigratable.md +29 -0
  41. package/docs/src/src/interfaces/IJBMultiTerminal.sol/interface.IJBMultiTerminal.md +50 -0
  42. package/docs/src/src/interfaces/IJBPayHook.sol/interface.IJBPayHook.md +28 -0
  43. package/docs/src/src/interfaces/IJBPayoutTerminal.sol/interface.IJBPayoutTerminal.md +105 -0
  44. package/docs/src/src/interfaces/IJBPermissioned.sol/interface.IJBPermissioned.md +12 -0
  45. package/docs/src/src/interfaces/IJBPermissions.sol/interface.IJBPermissions.md +74 -0
  46. package/docs/src/src/interfaces/IJBPermitTerminal.sol/interface.IJBPermitTerminal.md +15 -0
  47. package/docs/src/src/interfaces/IJBPriceFeed.sol/interface.IJBPriceFeed.md +12 -0
  48. package/docs/src/src/interfaces/IJBPrices.sol/interface.IJBPrices.md +74 -0
  49. package/docs/src/src/interfaces/IJBProjectUriRegistry.sol/interface.IJBProjectUriRegistry.md +19 -0
  50. package/docs/src/src/interfaces/IJBProjects.sol/interface.IJBProjects.md +49 -0
  51. package/docs/src/src/interfaces/IJBRulesetApprovalHook.sol/interface.IJBRulesetApprovalHook.md +35 -0
  52. package/docs/src/src/interfaces/IJBRulesetDataHook.sol/interface.IJBRulesetDataHook.md +97 -0
  53. package/docs/src/src/interfaces/IJBRulesets.sol/interface.IJBRulesets.md +165 -0
  54. package/docs/src/src/interfaces/IJBSplitHook.sol/interface.IJBSplitHook.md +31 -0
  55. package/docs/src/src/interfaces/IJBSplits.sol/interface.IJBSplits.md +35 -0
  56. package/docs/src/src/interfaces/IJBTerminal.sol/interface.IJBTerminal.md +141 -0
  57. package/docs/src/src/interfaces/IJBTerminalStore.sol/interface.IJBTerminalStore.md +198 -0
  58. package/docs/src/src/interfaces/IJBToken.sol/interface.IJBToken.md +54 -0
  59. package/docs/src/src/interfaces/IJBTokenUriResolver.sol/interface.IJBTokenUriResolver.md +12 -0
  60. package/docs/src/src/interfaces/IJBTokens.sol/interface.IJBTokens.md +151 -0
  61. package/docs/src/src/interfaces/README.md +33 -0
  62. package/docs/src/src/libraries/JBCashOuts.sol/library.JBCashOuts.md +40 -0
  63. package/docs/src/src/libraries/JBConstants.sol/library.JBConstants.md +52 -0
  64. package/docs/src/src/libraries/JBCurrencyIds.sol/library.JBCurrencyIds.md +19 -0
  65. package/docs/src/src/libraries/JBFees.sol/library.JBFees.md +52 -0
  66. package/docs/src/src/libraries/JBFixedPointNumber.sol/library.JBFixedPointNumber.md +12 -0
  67. package/docs/src/src/libraries/JBMetadataResolver.sol/library.JBMetadataResolver.md +242 -0
  68. package/docs/src/src/libraries/JBRulesetMetadataResolver.sol/library.JBRulesetMetadataResolver.md +180 -0
  69. package/docs/src/src/libraries/JBSplitGroupIds.sol/library.JBSplitGroupIds.md +14 -0
  70. package/docs/src/src/libraries/JBSurplus.sol/library.JBSurplus.md +44 -0
  71. package/docs/src/src/libraries/README.md +12 -0
  72. package/docs/src/src/periphery/JBDeadline1Day.sol/contract.JBDeadline1Day.md +15 -0
  73. package/docs/src/src/periphery/JBDeadline3Days.sol/contract.JBDeadline3Days.md +15 -0
  74. package/docs/src/src/periphery/JBDeadline3Hours.sol/contract.JBDeadline3Hours.md +15 -0
  75. package/docs/src/src/periphery/JBDeadline7Days.sol/contract.JBDeadline7Days.md +15 -0
  76. package/docs/src/src/periphery/JBMatchingPriceFeed.sol/contract.JBMatchingPriceFeed.md +22 -0
  77. package/docs/src/src/periphery/README.md +8 -0
  78. package/docs/src/src/structs/JBAccountingContext.sol/struct.JBAccountingContext.md +20 -0
  79. package/docs/src/src/structs/JBAfterCashOutRecordedContext.sol/struct.JBAfterCashOutRecordedContext.md +43 -0
  80. package/docs/src/src/structs/JBAfterPayRecordedContext.sol/struct.JBAfterPayRecordedContext.md +42 -0
  81. package/docs/src/src/structs/JBBeforeCashOutRecordedContext.sol/struct.JBBeforeCashOutRecordedContext.md +45 -0
  82. package/docs/src/src/structs/JBBeforePayRecordedContext.sol/struct.JBBeforePayRecordedContext.md +41 -0
  83. package/docs/src/src/structs/JBCashOutHookSpecification.sol/struct.JBCashOutHookSpecification.md +22 -0
  84. package/docs/src/src/structs/JBCurrencyAmount.sol/struct.JBCurrencyAmount.md +17 -0
  85. package/docs/src/src/structs/JBFee.sol/struct.JBFee.md +20 -0
  86. package/docs/src/src/structs/JBFundAccessLimitGroup.sol/struct.JBFundAccessLimitGroup.md +39 -0
  87. package/docs/src/src/structs/JBPayHookSpecification.sol/struct.JBPayHookSpecification.md +22 -0
  88. package/docs/src/src/structs/JBPermissionsData.sol/struct.JBPermissionsData.md +21 -0
  89. package/docs/src/src/structs/JBRuleset.sol/struct.JBRuleset.md +55 -0
  90. package/docs/src/src/structs/JBRulesetConfig.sol/struct.JBRulesetConfig.md +51 -0
  91. package/docs/src/src/structs/JBRulesetMetadata.sol/struct.JBRulesetMetadata.md +79 -0
  92. package/docs/src/src/structs/JBRulesetWeightCache.sol/struct.JBRulesetWeightCache.md +16 -0
  93. package/docs/src/src/structs/JBRulesetWithMetadata.sol/struct.JBRulesetWithMetadata.md +16 -0
  94. package/docs/src/src/structs/JBSingleAllowance.sol/struct.JBSingleAllowance.md +26 -0
  95. package/docs/src/src/structs/JBSplit.sol/struct.JBSplit.md +49 -0
  96. package/docs/src/src/structs/JBSplitGroup.sol/struct.JBSplitGroup.md +17 -0
  97. package/docs/src/src/structs/JBSplitHookContext.sol/struct.JBSplitHookContext.md +29 -0
  98. package/docs/src/src/structs/JBTerminalConfig.sol/struct.JBTerminalConfig.md +16 -0
  99. package/docs/src/src/structs/JBTokenAmount.sol/struct.JBTokenAmount.md +23 -0
  100. package/docs/src/src/structs/README.md +25 -0
  101. package/foundry.lock +11 -0
  102. package/foundry.toml +41 -0
  103. package/package.json +38 -0
  104. package/remappings.txt +1 -0
  105. package/script/Deploy.s.sol +111 -0
  106. package/script/DeployPeriphery.s.sol +287 -0
  107. package/script/helpers/CoreDeploymentLib.sol +121 -0
  108. package/slither-ci.config.json +10 -0
  109. package/sphinx.lock +507 -0
  110. package/src/JBChainlinkV3PriceFeed.sol +77 -0
  111. package/src/JBChainlinkV3SequencerPriceFeed.sol +75 -0
  112. package/src/JBController.sol +1186 -0
  113. package/src/JBDeadline.sol +73 -0
  114. package/src/JBDirectory.sol +343 -0
  115. package/src/JBERC20.sol +131 -0
  116. package/src/JBFeelessAddresses.sol +54 -0
  117. package/src/JBFundAccessLimits.sol +308 -0
  118. package/src/JBMultiTerminal.sol +2024 -0
  119. package/src/JBPermissions.sol +252 -0
  120. package/src/JBPrices.sol +227 -0
  121. package/src/JBProjects.sol +126 -0
  122. package/src/JBRulesets.sol +1093 -0
  123. package/src/JBSplits.sol +324 -0
  124. package/src/JBTerminalStore.sol +908 -0
  125. package/src/JBTokens.sol +376 -0
  126. package/src/abstract/JBControlled.sol +48 -0
  127. package/src/abstract/JBPermissioned.sol +77 -0
  128. package/src/enums/JBApprovalStatus.sol +12 -0
  129. package/src/interfaces/IJBCashOutHook.sol +15 -0
  130. package/src/interfaces/IJBCashOutTerminal.sol +51 -0
  131. package/src/interfaces/IJBControlled.sol +10 -0
  132. package/src/interfaces/IJBController.sol +280 -0
  133. package/src/interfaces/IJBDirectory.sol +69 -0
  134. package/src/interfaces/IJBDirectoryAccessControl.sol +15 -0
  135. package/src/interfaces/IJBFeeTerminal.sol +61 -0
  136. package/src/interfaces/IJBFeelessAddresses.sol +17 -0
  137. package/src/interfaces/IJBFundAccessLimits.sol +94 -0
  138. package/src/interfaces/IJBMigratable.sol +24 -0
  139. package/src/interfaces/IJBMultiTerminal.sol +36 -0
  140. package/src/interfaces/IJBPayHook.sol +14 -0
  141. package/src/interfaces/IJBPayoutTerminal.sol +92 -0
  142. package/src/interfaces/IJBPermissioned.sol +10 -0
  143. package/src/interfaces/IJBPermissions.sol +71 -0
  144. package/src/interfaces/IJBPermitTerminal.sol +14 -0
  145. package/src/interfaces/IJBPriceFeed.sol +10 -0
  146. package/src/interfaces/IJBPrices.sol +65 -0
  147. package/src/interfaces/IJBProjectUriRegistry.sol +15 -0
  148. package/src/interfaces/IJBProjects.sol +27 -0
  149. package/src/interfaces/IJBRulesetApprovalHook.sol +21 -0
  150. package/src/interfaces/IJBRulesetDataHook.sol +56 -0
  151. package/src/interfaces/IJBRulesets.sol +151 -0
  152. package/src/interfaces/IJBSplitHook.sol +16 -0
  153. package/src/interfaces/IJBSplits.sol +28 -0
  154. package/src/interfaces/IJBTerminal.sol +120 -0
  155. package/src/interfaces/IJBTerminalStore.sol +225 -0
  156. package/src/interfaces/IJBToken.sol +39 -0
  157. package/src/interfaces/IJBTokenUriResolver.sol +10 -0
  158. package/src/interfaces/IJBTokens.sol +113 -0
  159. package/src/libraries/JBCashOuts.sol +120 -0
  160. package/src/libraries/JBConstants.sol +14 -0
  161. package/src/libraries/JBCurrencyIds.sol +7 -0
  162. package/src/libraries/JBFees.sol +28 -0
  163. package/src/libraries/JBFixedPointNumber.sol +12 -0
  164. package/src/libraries/JBMetadataResolver.sol +306 -0
  165. package/src/libraries/JBRulesetMetadataResolver.sol +160 -0
  166. package/src/libraries/JBSplitGroupIds.sol +7 -0
  167. package/src/libraries/JBSurplus.sol +40 -0
  168. package/src/periphery/JBDeadline1Day.sol +8 -0
  169. package/src/periphery/JBDeadline3Days.sol +8 -0
  170. package/src/periphery/JBDeadline3Hours.sol +8 -0
  171. package/src/periphery/JBDeadline7Days.sol +8 -0
  172. package/src/periphery/JBMatchingPriceFeed.sol +13 -0
  173. package/src/structs/JBAccountingContext.sol +12 -0
  174. package/src/structs/JBAfterCashOutRecordedContext.sol +30 -0
  175. package/src/structs/JBAfterPayRecordedContext.sol +29 -0
  176. package/src/structs/JBBeforeCashOutRecordedContext.sol +31 -0
  177. package/src/structs/JBBeforePayRecordedContext.sol +28 -0
  178. package/src/structs/JBCashOutHookSpecification.sol +15 -0
  179. package/src/structs/JBCurrencyAmount.sol +10 -0
  180. package/src/structs/JBFee.sol +12 -0
  181. package/src/structs/JBFundAccessLimitGroup.sol +28 -0
  182. package/src/structs/JBPayHookSpecification.sol +15 -0
  183. package/src/structs/JBPermissionsData.sol +13 -0
  184. package/src/structs/JBRuleset.sol +42 -0
  185. package/src/structs/JBRulesetConfig.sol +43 -0
  186. package/src/structs/JBRulesetMetadata.sol +56 -0
  187. package/src/structs/JBRulesetWeightCache.sol +9 -0
  188. package/src/structs/JBRulesetWithMetadata.sol +12 -0
  189. package/src/structs/JBSingleAllowance.sol +16 -0
  190. package/src/structs/JBSplit.sol +37 -0
  191. package/src/structs/JBSplitGroup.sol +12 -0
  192. package/src/structs/JBSplitHookContext.sol +20 -0
  193. package/src/structs/JBTerminalConfig.sol +12 -0
  194. package/src/structs/JBTokenAmount.sol +14 -0
  195. package/test/AuditExploits.t.sol +2710 -0
  196. package/test/ComprehensiveInvariant.t.sol +298 -0
  197. package/test/EconomicSimulation.t.sol +340 -0
  198. package/test/EntryPointPermutations.t.sol +671 -0
  199. package/test/FlashLoanAttacks.t.sol +792 -0
  200. package/test/PermissionEscalation.t.sol +679 -0
  201. package/test/RulesetTransitions.t.sol +699 -0
  202. package/test/SplitLoopTests.t.sol +731 -0
  203. package/test/TestAccessToFunds.sol +2644 -0
  204. package/test/TestCashOut.sol +185 -0
  205. package/test/TestCashOutCountFor.sol +272 -0
  206. package/test/TestCashOutHooks.sol +317 -0
  207. package/test/TestCashOutTimingEdge.sol +229 -0
  208. package/test/TestDurationUnderflow.sol +220 -0
  209. package/test/TestFeeProcessingFailure.sol +208 -0
  210. package/test/TestFees.sol +604 -0
  211. package/test/TestInterfaceSupport.sol +62 -0
  212. package/test/TestJBERC20Inheritance.sol +91 -0
  213. package/test/TestLaunchProject.sol +176 -0
  214. package/test/TestMetaTx.sol +203 -0
  215. package/test/TestMetadataParserLib.sol +438 -0
  216. package/test/TestMigrationHeldFees.sol +249 -0
  217. package/test/TestMintTokensOf.sol +172 -0
  218. package/test/TestMultiTokenSurplus.sol +206 -0
  219. package/test/TestMultipleAccessLimits.sol +642 -0
  220. package/test/TestPayBurnRedeemFlow.sol +180 -0
  221. package/test/TestPayHooks.sol +190 -0
  222. package/test/TestPermissions.sol +305 -0
  223. package/test/TestPermissionsEdge.sol +286 -0
  224. package/test/TestPermit2Terminal.sol +339 -0
  225. package/test/TestRulesetQueueing.sol +1001 -0
  226. package/test/TestRulesetQueuingStress.sol +778 -0
  227. package/test/TestRulesetWeightCaching.sol +177 -0
  228. package/test/TestSplits.sol +369 -0
  229. package/test/TestTerminalMigration.sol +167 -0
  230. package/test/TestTokenFlow.sol +174 -0
  231. package/test/WeirdTokenTests.t.sol +764 -0
  232. package/test/formal/BondingCurveProperties.t.sol +411 -0
  233. package/test/formal/FeeProperties.t.sol +246 -0
  234. package/test/helpers/JBTest.sol +129 -0
  235. package/test/helpers/MetadataResolverHelper.sol +116 -0
  236. package/test/helpers/TestBaseWorkflow.sol +317 -0
  237. package/test/invariants/Phase3DeepInvariant.t.sol +404 -0
  238. package/test/invariants/RulesetsInvariant.t.sol +115 -0
  239. package/test/invariants/TerminalStoreInvariant.t.sol +220 -0
  240. package/test/invariants/TokensInvariant.t.sol +184 -0
  241. package/test/invariants/handlers/ComprehensiveHandler.sol +285 -0
  242. package/test/invariants/handlers/EconomicHandler.sol +347 -0
  243. package/test/invariants/handlers/Phase3Handler.sol +414 -0
  244. package/test/invariants/handlers/RulesetsHandler.sol +111 -0
  245. package/test/invariants/handlers/TerminalStoreHandler.sol +146 -0
  246. package/test/invariants/handlers/TokensHandler.sol +127 -0
  247. package/test/mock/ERC2771ForwarderMock.sol +37 -0
  248. package/test/mock/MockERC20.sol +18 -0
  249. package/test/mock/MockMaliciousBeneficiary.sol +67 -0
  250. package/test/mock/MockMaliciousSplitHook.sol +42 -0
  251. package/test/mock/MockPriceFeed.sol +20 -0
  252. package/test/trees/JBController/burnTokensOf.tree +9 -0
  253. package/test/trees/JBController/claimTokensFor.tree +5 -0
  254. package/test/trees/JBController/deployERC20For.tree +5 -0
  255. package/test/trees/JBController/getRulesetOf.tree +5 -0
  256. package/test/trees/JBController/launchProjectFor.tree +12 -0
  257. package/test/trees/JBController/launchRulesetsFor.tree +8 -0
  258. package/test/trees/JBController/migrateController.tree +12 -0
  259. package/test/trees/JBController/mintTokensOf.tree +12 -0
  260. package/test/trees/JBController/payReservedTokenToTerminal.tree +8 -0
  261. package/test/trees/JBController/receiveMigrationFrom.tree +4 -0
  262. package/test/trees/JBController/sendReservedTokensToSplitsOf.tree +12 -0
  263. package/test/trees/JBController/setMetadataOf.tree +5 -0
  264. package/test/trees/JBController/setSplitGroupsOf.tree +5 -0
  265. package/test/trees/JBController/setTokenFor.tree +5 -0
  266. package/test/trees/JBController/transferCreditsFrom.tree +8 -0
  267. package/test/trees/JBDirectory/primaryTerminalOf.tree +8 -0
  268. package/test/trees/JBDirectory/setControllerOf.tree +11 -0
  269. package/test/trees/JBDirectory/setPrimaryTerminalOf.tree +15 -0
  270. package/test/trees/JBDirectory/setTerminalsOf.tree +11 -0
  271. package/test/trees/JBERC20/initialize.tree +7 -0
  272. package/test/trees/JBERC20/name.tree +5 -0
  273. package/test/trees/JBERC20/nonces.tree +5 -0
  274. package/test/trees/JBERC20/symbol.tree +5 -0
  275. package/test/trees/JBFeelessAddresses/setFeelessAddress.tree +5 -0
  276. package/test/trees/JBFeelessAddresses/supportsInterface.tree +5 -0
  277. package/test/trees/JBFundAccessLimits/payoutLimitOf.tree +5 -0
  278. package/test/trees/JBFundAccessLimits/payoutLimitsOf.tree +8 -0
  279. package/test/trees/JBFundAccessLimits/setFundAccessLimitsFor.tree +18 -0
  280. package/test/trees/JBFundAccessLimits/surplusAllowanceOf.tree +5 -0
  281. package/test/trees/JBFundAccessLimits/surplusAllowancesOf.tree +8 -0
  282. package/test/trees/JBMetadataResolver/getDataFor.tree +8 -0
  283. package/test/trees/JBMultiTerminal/accountingContextsOf.tree +5 -0
  284. package/test/trees/JBMultiTerminal/addAccountingContextsFor.tree +10 -0
  285. package/test/trees/JBMultiTerminal/addToBalanceOf.tree +23 -0
  286. package/test/trees/JBMultiTerminal/cashOutTokensOf.tree +23 -0
  287. package/test/trees/JBMultiTerminal/executePayout.tree +32 -0
  288. package/test/trees/JBMultiTerminal/executeProcessFee.tree +14 -0
  289. package/test/trees/JBMultiTerminal/migrateBalanceOf.tree +12 -0
  290. package/test/trees/JBMultiTerminal/pay.tree +23 -0
  291. package/test/trees/JBMultiTerminal/processHeldFeesOf.tree +8 -0
  292. package/test/trees/JBMultiTerminal/sendPayoutsOf.tree +34 -0
  293. package/test/trees/JBMultiTerminal/useAllowanceOf.tree +16 -0
  294. package/test/trees/JBPermissions/hasPermission.tree +8 -0
  295. package/test/trees/JBPermissions/hasPermissions.tree +8 -0
  296. package/test/trees/JBPermissions/setPermissionsFor.tree +5 -0
  297. package/test/trees/JBPrices/addPriceFeedFor.tree +14 -0
  298. package/test/trees/JBPrices/pricePerUnitOf.tree +11 -0
  299. package/test/trees/JBProjects/createFor.tree +11 -0
  300. package/test/trees/JBProjects/setTokenUriResolver.tree +5 -0
  301. package/test/trees/JBProjects/supportsInterface.tree +9 -0
  302. package/test/trees/JBProjects/tokenURI.tree +5 -0
  303. package/test/trees/JBRulesets/currentApprovalStatusForLatestRulesetOf.tree +8 -0
  304. package/test/trees/JBRulesets/currentOf.tree +12 -0
  305. package/test/trees/JBRulesets/getRulesetOf.tree +5 -0
  306. package/test/trees/JBRulesets/latestQueuedRulesetOf.tree +10 -0
  307. package/test/trees/JBRulesets/rulesetsOf.tree +11 -0
  308. package/test/trees/JBRulesets/upcomingRulesetOf.tree +20 -0
  309. package/test/trees/JBRulesets/updateRulesetWeightCache.tree +5 -0
  310. package/test/trees/JBSplits/setSplitGroupsOf.tree +17 -0
  311. package/test/trees/JBSplits/splitsOf.tree +5 -0
  312. package/test/trees/JBTerminalStore/currentReclaimableSurplusOf.tree +16 -0
  313. package/test/trees/JBTerminalStore/currentSurplusOf.tree +25 -0
  314. package/test/trees/JBTerminalStore/currentTotalSurplusOf.tree +5 -0
  315. package/test/trees/JBTerminalStore/recordCashOutsFor.tree +16 -0
  316. package/test/trees/JBTerminalStore/recordPaymentFrom.tree +14 -0
  317. package/test/trees/JBTerminalStore/recordPayoutFor.tree +10 -0
  318. package/test/trees/JBTerminalStore/recordTerminalMigration.tree +5 -0
  319. package/test/trees/JBTerminalStore/recordUsedAllowanceOf.tree +10 -0
  320. package/test/trees/JBTokens/burnFrom.tree +10 -0
  321. package/test/trees/JBTokens/claimTokensFor.tree +10 -0
  322. package/test/trees/JBTokens/deployERC20For.tree +12 -0
  323. package/test/trees/JBTokens/mintFor.tree +10 -0
  324. package/test/trees/JBTokens/setTokenFor.tree +11 -0
  325. package/test/trees/JBTokens/totalBalanceOf.tree +5 -0
  326. package/test/trees/JBTokens/totalSupplyOf.tree +5 -0
  327. package/test/trees/JBTokens/transferCreditsFrom.tree +8 -0
  328. package/test/trees/mintTokensOf.tree +12 -0
  329. package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +220 -0
  330. package/test/units/static/JBController/JBControllerSetup.sol +40 -0
  331. package/test/units/static/JBController/TestBurnTokensOf.sol +107 -0
  332. package/test/units/static/JBController/TestClaimTokensFor.sol +60 -0
  333. package/test/units/static/JBController/TestDeployErc20For.sol +80 -0
  334. package/test/units/static/JBController/TestLaunchProjectFor.sol +282 -0
  335. package/test/units/static/JBController/TestLaunchRulesetsFor.sol +322 -0
  336. package/test/units/static/JBController/TestMigrateController.sol +148 -0
  337. package/test/units/static/JBController/TestMintTokensOfUnits.sol +102 -0
  338. package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +71 -0
  339. package/test/units/static/JBController/TestReceiveMigrationFrom.sol +95 -0
  340. package/test/units/static/JBController/TestRulesetViews.sol +219 -0
  341. package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +595 -0
  342. package/test/units/static/JBController/TestSetSplitGroupsOf.sol +63 -0
  343. package/test/units/static/JBController/TestSetTokenFor.sol +227 -0
  344. package/test/units/static/JBController/TestSetUriOf.sol +53 -0
  345. package/test/units/static/JBController/TestTransferCreditsFrom.sol +159 -0
  346. package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +194 -0
  347. package/test/units/static/JBDirectory/JBDirectorySetup.sol +22 -0
  348. package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +122 -0
  349. package/test/units/static/JBDirectory/TestSetControllerOf.sol +173 -0
  350. package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +98 -0
  351. package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +169 -0
  352. package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +128 -0
  353. package/test/units/static/JBERC20/JBERC20Setup.sol +20 -0
  354. package/test/units/static/JBERC20/SigUtils.sol +34 -0
  355. package/test/units/static/JBERC20/TestInitialize.sol +54 -0
  356. package/test/units/static/JBERC20/TestName.sol +30 -0
  357. package/test/units/static/JBERC20/TestNonces.sol +59 -0
  358. package/test/units/static/JBERC20/TestSymbol.sol +31 -0
  359. package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +20 -0
  360. package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +29 -0
  361. package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +35 -0
  362. package/test/units/static/JBFees/TestFeesFuzz.sol +78 -0
  363. package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +16 -0
  364. package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +71 -0
  365. package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +21 -0
  366. package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +159 -0
  367. package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +56 -0
  368. package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +94 -0
  369. package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +182 -0
  370. package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +61 -0
  371. package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +96 -0
  372. package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +89 -0
  373. package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +227 -0
  374. package/test/units/static/JBMetadataResolver/TestMetadataResolverM20M21.sol +245 -0
  375. package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +39 -0
  376. package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +65 -0
  377. package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +313 -0
  378. package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +432 -0
  379. package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +478 -0
  380. package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +577 -0
  381. package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +176 -0
  382. package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +190 -0
  383. package/test/units/static/JBMultiTerminal/TestPay.sol +514 -0
  384. package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +29 -0
  385. package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +243 -0
  386. package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +310 -0
  387. package/test/units/static/JBPermissions/JBPermissionsSetup.sol +18 -0
  388. package/test/units/static/JBPermissions/TestHasPermission.sol +50 -0
  389. package/test/units/static/JBPermissions/TestHasPermissions.sol +93 -0
  390. package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +62 -0
  391. package/test/units/static/JBPrices/JBPricesSetup.sol +26 -0
  392. package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +102 -0
  393. package/test/units/static/JBPrices/TestPricePerUnitOf.sol +129 -0
  394. package/test/units/static/JBPrices/TestPrices.sol +262 -0
  395. package/test/units/static/JBProjects/JBProjectsSetup.sol +20 -0
  396. package/test/units/static/JBProjects/TestCreateFor.sol +69 -0
  397. package/test/units/static/JBProjects/TestInitialProject.sol +19 -0
  398. package/test/units/static/JBProjects/TestInterfaces.sol +27 -0
  399. package/test/units/static/JBProjects/TestSetResolver.sol +36 -0
  400. package/test/units/static/JBProjects/TestTokenUri.sol +38 -0
  401. package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +99 -0
  402. package/test/units/static/JBRulesets/JBRulesetsSetup.sol +21 -0
  403. package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +257 -0
  404. package/test/units/static/JBRulesets/TestCurrentOf.sol +231 -0
  405. package/test/units/static/JBRulesets/TestGetRulesetOf.sol +94 -0
  406. package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +252 -0
  407. package/test/units/static/JBRulesets/TestRulesets.sol +617 -0
  408. package/test/units/static/JBRulesets/TestRulesetsOf.sol +37 -0
  409. package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +526 -0
  410. package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +91 -0
  411. package/test/units/static/JBSplits/JBSplitsSetup.sol +23 -0
  412. package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +502 -0
  413. package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +370 -0
  414. package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +262 -0
  415. package/test/units/static/JBSplits/TestSplitsOf.sol +24 -0
  416. package/test/units/static/JBSplits/TestSplitsPacking.sol +33 -0
  417. package/test/units/static/JBSurplus/TestSurplusFuzz.sol +125 -0
  418. package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +23 -0
  419. package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +434 -0
  420. package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +428 -0
  421. package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +65 -0
  422. package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +479 -0
  423. package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +508 -0
  424. package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +257 -0
  425. package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +131 -0
  426. package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +390 -0
  427. package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +187 -0
  428. package/test/units/static/JBTokens/JBTokensSetup.sol +23 -0
  429. package/test/units/static/JBTokens/TestBurnFrom.sol +104 -0
  430. package/test/units/static/JBTokens/TestClaimTokensFor.sol +107 -0
  431. package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +89 -0
  432. package/test/units/static/JBTokens/TestMintFor.sol +97 -0
  433. package/test/units/static/JBTokens/TestSetTokenFor.sol +95 -0
  434. package/test/units/static/JBTokens/TestTotalBalanceOf.sol +65 -0
  435. package/test/units/static/JBTokens/TestTotalSupplyOf.sol +56 -0
  436. package/test/units/static/JBTokens/TestTransferCreditsFrom.sol +54 -0
@@ -0,0 +1,252 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.23;
3
+
4
+ import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol";
5
+ import {JBPermissionIds} from "@bananapus/permission-ids-v6/src/JBPermissionIds.sol";
6
+
7
+ import {IJBPermissions} from "./interfaces/IJBPermissions.sol";
8
+ import {JBPermissionsData} from "./structs/JBPermissionsData.sol";
9
+
10
+ /// @notice Stores permissions for all addresses and operators. Addresses can give permissions to any other address
11
+ /// (i.e. an *operator*) to execute specific operations on their behalf.
12
+ contract JBPermissions is ERC2771Context, IJBPermissions {
13
+ //*********************************************************************//
14
+ // --------------------------- custom errors ------------------------- //
15
+ //*********************************************************************//
16
+
17
+ error JBPermissions_CantSetRootPermissionForWildcardProject();
18
+ error JBPermissions_NoZeroPermission();
19
+ error JBPermissions_PermissionIdOutOfBounds(uint256 permissionId);
20
+ error JBPermissions_Unauthorized(address account, address operator, uint256 projectId, uint256 permissionId);
21
+
22
+ //*********************************************************************//
23
+ // ------------------------- public constants ------------------------ //
24
+ //*********************************************************************//
25
+
26
+ /// @notice The project ID considered a wildcard, meaning it will grant permissions to all projects.
27
+ uint256 public constant override WILDCARD_PROJECT_ID = 0;
28
+
29
+ //*********************************************************************//
30
+ // --------------------- public stored properties -------------------- //
31
+ //*********************************************************************//
32
+
33
+ /// @notice The permissions that an operator has been given by an account for a specific project.
34
+ /// @dev An account can give an operator permissions that only pertain to a specific project ID.
35
+ /// @dev There is no project with a ID of 0 – this ID is a wildcard which gives an operator permissions pertaining
36
+ /// to *all* project IDs on an account's behalf. Use this with caution.
37
+ /// @dev Permissions are stored in a packed `uint256`. Each of the 256 bits represents the on/off state of a
38
+ /// permission. Applications can specify the significance of each permission ID.
39
+ /// @custom:param operator The address of the operator.
40
+ /// @custom:param account The address of the account being operated on behalf of.
41
+ /// @custom:param projectId The project ID the permissions are scoped to. An ID of 0 grants permissions across all
42
+ /// projects.
43
+ mapping(address operator => mapping(address account => mapping(uint256 projectId => uint256)))
44
+ public
45
+ override permissionsOf;
46
+
47
+ //*********************************************************************//
48
+ // ---------------------------- constructor -------------------------- //
49
+ //*********************************************************************//
50
+
51
+ /// @param trustedForwarder The trusted forwarder for the ERC2771Context.
52
+ constructor(address trustedForwarder) ERC2771Context(trustedForwarder) {}
53
+
54
+ //*********************************************************************//
55
+ // -------------------------- public views --------------------------- //
56
+ //*********************************************************************//
57
+
58
+ /// @notice Check if an operator has a specific permission for a specific address and project ID.
59
+ /// @param operator The operator to check.
60
+ /// @param account The account being operated on behalf of.
61
+ /// @param projectId The project ID that the operator has permission to operate under. 0 represents all projects.
62
+ /// @param permissionId The permission ID to check for.
63
+ /// @param includeRoot A flag indicating if the return value should default to true if the operator has the ROOT
64
+ /// permission.
65
+ /// @param includeWildcardProjectId A flag indicating if the return value should return true if the operator has the
66
+ /// specified permission on the wildcard project ID.
67
+ /// @return A flag indicating whether the operator has the specified permission.
68
+ function hasPermission(
69
+ address operator,
70
+ address account,
71
+ uint256 projectId,
72
+ uint256 permissionId,
73
+ bool includeRoot,
74
+ bool includeWildcardProjectId
75
+ )
76
+ public
77
+ view
78
+ override
79
+ returns (bool)
80
+ {
81
+ // Indexes above 255 don't exist
82
+ if (permissionId > 255) revert JBPermissions_PermissionIdOutOfBounds(permissionId);
83
+
84
+ // If the ROOT permission is set and should be included, return true.
85
+ if (
86
+ includeRoot
87
+ && (_includesPermission({
88
+ permissions: permissionsOf[operator][account][projectId], permissionId: JBPermissionIds.ROOT
89
+ })
90
+ || (includeWildcardProjectId
91
+ && _includesPermission({
92
+ permissions: permissionsOf[operator][account][WILDCARD_PROJECT_ID],
93
+ permissionId: JBPermissionIds.ROOT
94
+ })))
95
+ ) {
96
+ return true;
97
+ }
98
+
99
+ // Otherwise return the t/f flag of the specified id.
100
+ return _includesPermission({
101
+ permissions: permissionsOf[operator][account][projectId], permissionId: permissionId
102
+ })
103
+ || (includeWildcardProjectId
104
+ && _includesPermission({
105
+ permissions: permissionsOf[operator][account][WILDCARD_PROJECT_ID], permissionId: permissionId
106
+ }));
107
+ }
108
+
109
+ /// @notice Check if an operator has all of the specified permissions for a specific address and project ID.
110
+ /// @param operator The operator to check.
111
+ /// @param account The account being operated on behalf of.
112
+ /// @param projectId The project ID that the operator has permission to operate under. 0 represents all projects.
113
+ /// @param permissionIds An array of permission IDs to check for.
114
+ /// @param includeRoot A flag indicating if the return value should default to true if the operator has the ROOT
115
+ /// permission.
116
+ /// @param includeWildcardProjectId A flag indicating if the return value should return true if the operator has the
117
+ /// specified permission on the wildcard project ID.
118
+ /// @return A flag indicating whether the operator has all specified permissions.
119
+ function hasPermissions(
120
+ address operator,
121
+ address account,
122
+ uint256 projectId,
123
+ uint256[] calldata permissionIds,
124
+ bool includeRoot,
125
+ bool includeWildcardProjectId
126
+ )
127
+ external
128
+ view
129
+ override
130
+ returns (bool)
131
+ {
132
+ // If the ROOT permission is set and should be included, return true.
133
+ if (
134
+ includeRoot
135
+ && (_includesPermission({
136
+ permissions: permissionsOf[operator][account][projectId], permissionId: JBPermissionIds.ROOT
137
+ })
138
+ || (includeWildcardProjectId
139
+ && _includesPermission({
140
+ permissions: permissionsOf[operator][account][WILDCARD_PROJECT_ID],
141
+ permissionId: JBPermissionIds.ROOT
142
+ })))
143
+ ) {
144
+ return true;
145
+ }
146
+
147
+ // Keep a reference to the permission item being checked.
148
+ uint256 operatorAccountProjectPermissions = permissionsOf[operator][account][projectId];
149
+
150
+ // Keep a reference to the wildcard project permissions.
151
+ uint256 operatorAccountWildcardProjectPermissions =
152
+ includeWildcardProjectId ? permissionsOf[operator][account][WILDCARD_PROJECT_ID] : 0;
153
+
154
+ for (uint256 i; i < permissionIds.length; i++) {
155
+ // Set the permission being iterated on.
156
+ uint256 permissionId = permissionIds[i];
157
+
158
+ // Indexes above 255 don't exist
159
+ if (permissionId > 255) revert JBPermissions_PermissionIdOutOfBounds(permissionId);
160
+
161
+ // Check each permissionId
162
+ if (
163
+ !_includesPermission({permissions: operatorAccountProjectPermissions, permissionId: permissionId})
164
+ && !_includesPermission({
165
+ permissions: operatorAccountWildcardProjectPermissions, permissionId: permissionId
166
+ })
167
+ ) {
168
+ return false;
169
+ }
170
+ }
171
+ return true;
172
+ }
173
+
174
+ //*********************************************************************//
175
+ // -------------------------- internal views ------------------------- //
176
+ //*********************************************************************//
177
+
178
+ /// @notice Checks if a permission is included in a packed permissions data.
179
+ /// @param permissions The packed permissions to check.
180
+ /// @param permissionId The ID of the permission to check for.
181
+ /// @return A flag indicating whether the permission is included.
182
+ function _includesPermission(uint256 permissions, uint256 permissionId) internal pure returns (bool) {
183
+ return ((permissions >> permissionId) & 1) == 1;
184
+ }
185
+
186
+ /// @notice Converts an array of permission IDs to a packed `uint256`.
187
+ /// @param permissionIds The IDs of the permissions to pack.
188
+ /// @return packed The packed value.
189
+ function _packedPermissions(uint8[] calldata permissionIds) internal pure returns (uint256 packed) {
190
+ for (uint256 i; i < permissionIds.length; i++) {
191
+ // Set the permission being iterated on.
192
+ uint256 permissionId = permissionIds[i];
193
+
194
+ // Turn on the bit at the ID.
195
+ packed |= 1 << permissionId;
196
+ }
197
+ }
198
+
199
+ //*********************************************************************//
200
+ // ---------------------- external transactions ---------------------- //
201
+ //*********************************************************************//
202
+
203
+ /// @notice Sets permissions for an operator.
204
+ /// @dev Only an address can give permissions to or revoke permissions from its operators.
205
+ /// @param account The account setting its operators' permissions.
206
+ /// @param permissionsData The data which specifies the permissions the operator is being given.
207
+ function setPermissionsFor(address account, JBPermissionsData calldata permissionsData) external override {
208
+ // Pack the permission IDs into a uint256.
209
+ uint256 packed = _packedPermissions(permissionsData.permissionIds);
210
+
211
+ // Make sure the 0 permission is not set.
212
+ if (_includesPermission({permissions: packed, permissionId: 0})) revert JBPermissions_NoZeroPermission();
213
+
214
+ // Cache the sender.
215
+ address msgSender = _msgSender();
216
+
217
+ // Enforce permissions. ROOT operators are allowed to set permissions so long as they are not setting another
218
+ // ROOT permission or setting permissions for a wildcard project ID.
219
+ if (
220
+ msgSender != account
221
+ && (_includesPermission({permissions: packed, permissionId: JBPermissionIds.ROOT})
222
+ || permissionsData.projectId == WILDCARD_PROJECT_ID
223
+ || !hasPermission({
224
+ operator: msgSender,
225
+ account: account,
226
+ projectId: permissionsData.projectId,
227
+ permissionId: JBPermissionIds.ROOT,
228
+ includeRoot: true,
229
+ includeWildcardProjectId: true
230
+ }))
231
+ ) {
232
+ revert JBPermissions_Unauthorized({
233
+ account: account,
234
+ operator: msgSender,
235
+ projectId: permissionsData.projectId,
236
+ permissionId: JBPermissionIds.ROOT
237
+ });
238
+ }
239
+
240
+ // Store the new value.
241
+ permissionsOf[permissionsData.operator][account][permissionsData.projectId] = packed;
242
+
243
+ emit OperatorPermissionsSet({
244
+ operator: permissionsData.operator,
245
+ account: account,
246
+ projectId: permissionsData.projectId,
247
+ permissionIds: permissionsData.permissionIds,
248
+ packed: packed,
249
+ caller: msgSender
250
+ });
251
+ }
252
+ }
@@ -0,0 +1,227 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.23;
3
+
4
+ import {ERC2771Context, Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol";
5
+ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
6
+ import {mulDiv} from "@prb/math/src/Common.sol";
7
+
8
+ import {JBControlled} from "./abstract/JBControlled.sol";
9
+ import {JBPermissioned} from "./abstract/JBPermissioned.sol";
10
+ import {IJBDirectory} from "./interfaces/IJBDirectory.sol";
11
+ import {IJBPermissions} from "./interfaces/IJBPermissions.sol";
12
+ import {IJBPriceFeed} from "./interfaces/IJBPriceFeed.sol";
13
+ import {IJBPrices} from "./interfaces/IJBPrices.sol";
14
+ import {IJBProjects} from "./interfaces/IJBProjects.sol";
15
+
16
+ /// @notice Manages and normalizes price feeds. Price feeds are contracts which return the "pricing currency" cost of 1
17
+ /// "unit currency".
18
+ /// @dev Price feeds are immutable once set and cannot be replaced or removed. If a price feed needs to be changed,
19
+ /// a new JBPrices contract must be deployed and projects must migrate to use it.
20
+ contract JBPrices is JBControlled, JBPermissioned, ERC2771Context, Ownable, IJBPrices {
21
+ //*********************************************************************//
22
+ // --------------------------- custom errors ------------------------- //
23
+ //*********************************************************************//
24
+
25
+ error JBPrices_PriceFeedAlreadyExists(IJBPriceFeed feed);
26
+ error JBPrices_PriceFeedNotFound();
27
+ error JBPrices_ZeroPricingCurrency();
28
+ error JBPrices_ZeroUnitCurrency();
29
+
30
+ //*********************************************************************//
31
+ // ------------------------- public constants ------------------------ //
32
+ //*********************************************************************//
33
+
34
+ /// @notice The ID to store default values in.
35
+ uint256 public constant override DEFAULT_PROJECT_ID = 0;
36
+
37
+ //*********************************************************************//
38
+ // ---------------- public immutable stored properties --------------- //
39
+ //*********************************************************************//
40
+
41
+ /// @notice Mints ERC-721s that represent project ownership and transfers.
42
+ IJBProjects public immutable override PROJECTS;
43
+
44
+ //*********************************************************************//
45
+ // --------------------- public stored properties -------------------- //
46
+ //*********************************************************************//
47
+
48
+ /// @notice The available price feeds.
49
+ /// @dev The feed returns the `pricingCurrency` cost for one unit of the `unitCurrency`.
50
+ /// @custom:param projectId The ID of the project the feed applies to. Feeds stored in ID 0 are used by default for
51
+ /// all projects.
52
+ /// @custom:param pricingCurrency The currency the feed's resulting price is in terms of.
53
+ /// @custom:param unitCurrency The currency being priced by the feed.
54
+ mapping(uint256 projectId => mapping(uint256 pricingCurrency => mapping(uint256 unitCurrency => IJBPriceFeed)))
55
+ public
56
+ override priceFeedFor;
57
+
58
+ //*********************************************************************//
59
+ // ---------------------------- constructor -------------------------- //
60
+ //*********************************************************************//
61
+
62
+ /// @param directory A contract storing directories of terminals and controllers for each project.
63
+ /// @param permissions A contract storing permissions.
64
+ /// @param projects A contract which mints ERC-721s that represent project ownership and transfers.
65
+ /// @param owner The address that will own the contract.
66
+ /// @param trustedForwarder The trusted forwarder for the ERC2771Context.
67
+ constructor(
68
+ IJBDirectory directory,
69
+ IJBPermissions permissions,
70
+ IJBProjects projects,
71
+ address owner,
72
+ address trustedForwarder
73
+ )
74
+ JBControlled(directory)
75
+ JBPermissioned(permissions)
76
+ Ownable(owner)
77
+ ERC2771Context(trustedForwarder)
78
+ {
79
+ PROJECTS = projects;
80
+ }
81
+
82
+ //*********************************************************************//
83
+ // -------------------------- public views --------------------------- //
84
+ //*********************************************************************//
85
+
86
+ /// @notice Gets the `pricingCurrency` cost for one unit of the `unitCurrency`.
87
+ /// @param projectId The ID of the project to check the feed for. Feeds stored in ID 0 are used by default for all
88
+ /// projects.
89
+ /// @param pricingCurrency The currency the feed's resulting price is in terms of.
90
+ /// @param unitCurrency The currency being priced by the feed.
91
+ /// @param decimals The number of decimals the returned fixed point price should include.
92
+ /// @return The `pricingCurrency` price of 1 `unitCurrency`, as a fixed point number with the specified number of
93
+ /// decimals.
94
+ function pricePerUnitOf(
95
+ uint256 projectId,
96
+ uint256 pricingCurrency,
97
+ uint256 unitCurrency,
98
+ uint256 decimals
99
+ )
100
+ public
101
+ view
102
+ override
103
+ returns (uint256)
104
+ {
105
+ // If the `pricingCurrency` is the `unitCurrency`, return 1 since they have the same price. Include the
106
+ // desired number of decimals.
107
+ if (pricingCurrency == unitCurrency) return 10 ** decimals;
108
+
109
+ // Get a reference to the price feed.
110
+ IJBPriceFeed feed = priceFeedFor[projectId][pricingCurrency][unitCurrency];
111
+
112
+ // If the feed exists, return its price.
113
+ if (feed != IJBPriceFeed(address(0))) return feed.currentUnitPrice(decimals);
114
+
115
+ // Try getting the inverse feed.
116
+ feed = priceFeedFor[projectId][unitCurrency][pricingCurrency];
117
+
118
+ // If it exists, return the inverse of its price.
119
+ // @dev The inverse calculation `(10^d * 10^d) / price` has acceptable precision when the feed price
120
+ // is in the range of ~1e9 to ~1e27 (for 18 decimals). Extreme prices outside this range may lose
121
+ // significant precision due to fixed-point division truncation.
122
+ if (feed != IJBPriceFeed(address(0))) {
123
+ return mulDiv(10 ** decimals, 10 ** decimals, feed.currentUnitPrice(decimals));
124
+ }
125
+
126
+ // Check for a default feed (project ID 0) if not found.
127
+ if (projectId != DEFAULT_PROJECT_ID) {
128
+ return pricePerUnitOf({
129
+ projectId: DEFAULT_PROJECT_ID,
130
+ pricingCurrency: pricingCurrency,
131
+ unitCurrency: unitCurrency,
132
+ decimals: decimals
133
+ });
134
+ }
135
+
136
+ // No price feed available, revert.
137
+ revert JBPrices_PriceFeedNotFound();
138
+ }
139
+
140
+ //*********************************************************************//
141
+ // -------------------------- internal views ------------------------- //
142
+ //*********************************************************************//
143
+
144
+ /// @dev `ERC-2771` specifies the context as being a single address (20 bytes).
145
+ function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
146
+ return super._contextSuffixLength();
147
+ }
148
+
149
+ /// @notice The calldata. Preferred to use over `msg.data`.
150
+ /// @return calldata The `msg.data` of this call.
151
+ function _msgData() internal view override(ERC2771Context, Context) returns (bytes calldata) {
152
+ return ERC2771Context._msgData();
153
+ }
154
+
155
+ /// @notice The message's sender. Preferred to use over `msg.sender`.
156
+ /// @return sender The address which sent this call.
157
+ function _msgSender() internal view override(ERC2771Context, Context) returns (address sender) {
158
+ return ERC2771Context._msgSender();
159
+ }
160
+
161
+ //*********************************************************************//
162
+ // ---------------------- external transactions ---------------------- //
163
+ //*********************************************************************//
164
+
165
+ /// @notice Add a price feed for the `unitCurrency`, priced in terms of the `pricingCurrency`.
166
+ /// @dev Price feeds can only be added, not modified or removed. Once a feed is set for a currency pair (in either
167
+ /// direction), it is permanent for that project ID. Recovery from a misconfigured feed requires deploying a new
168
+ /// JBPrices contract.
169
+ /// @dev This contract's owner can add protocol-wide default price feed by passing a `projectId` of 0.
170
+ /// @param projectId The ID of the project to add a feed for. If `projectId` is 0, add a protocol-wide default price
171
+ /// feed.
172
+ /// @param pricingCurrency The currency the feed's output price is in terms of.
173
+ /// @param unitCurrency The currency being priced by the feed.
174
+ /// @param feed The address of the price feed to add.
175
+ function addPriceFeedFor(
176
+ uint256 projectId,
177
+ uint256 pricingCurrency,
178
+ uint256 unitCurrency,
179
+ IJBPriceFeed feed
180
+ )
181
+ external
182
+ override
183
+ {
184
+ // Ensure default price feeds can only be set by this contract's owner, and that other `projectId`s can only be
185
+ // set by the controller
186
+ projectId == DEFAULT_PROJECT_ID ? _checkOwner() : _onlyControllerOf(projectId);
187
+
188
+ // Make sure the pricing currency isn't 0.
189
+ if (pricingCurrency == 0) revert JBPrices_ZeroPricingCurrency();
190
+
191
+ // Make sure the unit currency isn't 0.
192
+ if (unitCurrency == 0) revert JBPrices_ZeroUnitCurrency();
193
+
194
+ // Make sure there isn't already a default price feed for the pair or its inverse.
195
+ if (
196
+ priceFeedFor[DEFAULT_PROJECT_ID][pricingCurrency][unitCurrency] != IJBPriceFeed(address(0))
197
+ || priceFeedFor[DEFAULT_PROJECT_ID][unitCurrency][pricingCurrency] != IJBPriceFeed(address(0))
198
+ ) {
199
+ revert JBPrices_PriceFeedAlreadyExists(priceFeedFor[DEFAULT_PROJECT_ID][pricingCurrency][unitCurrency]
200
+ != IJBPriceFeed(address(0))
201
+ ? priceFeedFor[DEFAULT_PROJECT_ID][pricingCurrency][unitCurrency]
202
+ : priceFeedFor[DEFAULT_PROJECT_ID][unitCurrency][pricingCurrency]);
203
+ }
204
+
205
+ // Make sure this project doesn't already have a price feed for the pair or its inverse.
206
+ if (
207
+ priceFeedFor[projectId][pricingCurrency][unitCurrency] != IJBPriceFeed(address(0))
208
+ || priceFeedFor[projectId][unitCurrency][pricingCurrency] != IJBPriceFeed(address(0))
209
+ ) {
210
+ revert JBPrices_PriceFeedAlreadyExists(priceFeedFor[projectId][pricingCurrency][unitCurrency]
211
+ != IJBPriceFeed(address(0))
212
+ ? priceFeedFor[projectId][pricingCurrency][unitCurrency]
213
+ : priceFeedFor[projectId][unitCurrency][pricingCurrency]);
214
+ }
215
+
216
+ // Store the feed.
217
+ priceFeedFor[projectId][pricingCurrency][unitCurrency] = feed;
218
+
219
+ emit AddPriceFeed({
220
+ projectId: projectId,
221
+ pricingCurrency: pricingCurrency,
222
+ unitCurrency: unitCurrency,
223
+ feed: feed,
224
+ caller: _msgSender()
225
+ });
226
+ }
227
+ }
@@ -0,0 +1,126 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.23;
3
+
4
+ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
5
+ import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol";
6
+ import {ERC721, Context} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
7
+ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
8
+
9
+ import {IJBProjects} from "./interfaces/IJBProjects.sol";
10
+ import {IJBTokenUriResolver} from "./interfaces/IJBTokenUriResolver.sol";
11
+
12
+ /// @notice Stores project ownership and metadata.
13
+ /// @dev Projects are represented as ERC-721s.
14
+ contract JBProjects is ERC721, ERC2771Context, Ownable, IJBProjects {
15
+ //*********************************************************************//
16
+ // --------------------- public stored properties -------------------- //
17
+ //*********************************************************************//
18
+
19
+ /// @notice The number of projects that have been created using this contract.
20
+ /// @dev The count is incremented with each new project created.
21
+ /// @dev The resulting ERC-721 token ID for each project is the newly incremented count value.
22
+ uint256 public override count;
23
+
24
+ /// @notice The contract resolving each project ID to its ERC721 URI.
25
+ IJBTokenUriResolver public override tokenUriResolver;
26
+
27
+ //*********************************************************************//
28
+ // -------------------------- constructor ---------------------------- //
29
+ //*********************************************************************//
30
+
31
+ /// @param owner The owner of the contract who can set metadata.
32
+ /// @param feeProjectOwner The address that will receive the fee-project. If `address(0)` the fee-project will not
33
+ /// be minted.
34
+ /// @param trustedForwarder The trusted forwarder for the ERC2771Context.
35
+ constructor(
36
+ address owner,
37
+ address feeProjectOwner,
38
+ address trustedForwarder
39
+ )
40
+ ERC721("Juicebox Projects", "JUICEBOX")
41
+ Ownable(owner)
42
+ ERC2771Context(trustedForwarder)
43
+ {
44
+ if (feeProjectOwner != address(0)) {
45
+ createFor(feeProjectOwner);
46
+ }
47
+ }
48
+
49
+ //*********************************************************************//
50
+ // -------------------------- public views --------------------------- //
51
+ //*********************************************************************//
52
+
53
+ /// @notice Indicates whether this contract adheres to the specified interface.
54
+ /// @dev See {IERC165-supportsInterface}.
55
+ /// @param interfaceId The ID of the interface to check for adherence to.
56
+ /// @return A flag indicating if the provided interface ID is supported.
57
+ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
58
+ return interfaceId == type(IJBProjects).interfaceId || super.supportsInterface(interfaceId);
59
+ }
60
+
61
+ /// @notice Returns the URI where the ERC-721 standard JSON of a project is hosted.
62
+ /// @param projectId The ID of the project to get a URI of.
63
+ /// @return The token URI to use for the provided `projectId`.
64
+ function tokenURI(uint256 projectId) public view override returns (string memory) {
65
+ // Keep a reference to the resolver.
66
+ IJBTokenUriResolver resolver = tokenUriResolver;
67
+
68
+ // If there's no resolver, there's no URI.
69
+ if (resolver == IJBTokenUriResolver(address(0))) return "";
70
+
71
+ // Return the resolved URI.
72
+ return resolver.getUri(projectId);
73
+ }
74
+
75
+ //*********************************************************************//
76
+ // -------------------------- internal views ------------------------- //
77
+ //*********************************************************************//
78
+
79
+ /// @dev `ERC-2771` specifies the context as being a single address (20 bytes).
80
+ function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
81
+ return super._contextSuffixLength();
82
+ }
83
+
84
+ /// @notice The calldata. Preferred to use over `msg.data`.
85
+ /// @return calldata The `msg.data` of this call.
86
+ function _msgData() internal view override(ERC2771Context, Context) returns (bytes calldata) {
87
+ return ERC2771Context._msgData();
88
+ }
89
+
90
+ /// @notice The message's sender. Preferred to use over `msg.sender`.
91
+ /// @return sender The address which sent this call.
92
+ function _msgSender() internal view override(ERC2771Context, Context) returns (address sender) {
93
+ return ERC2771Context._msgSender();
94
+ }
95
+
96
+ //*********************************************************************//
97
+ // ---------------------- external transactions ---------------------- //
98
+ //*********************************************************************//
99
+
100
+ /// @notice Sets the address of the resolver used to retrieve the tokenURI of projects.
101
+ /// @param resolver The address of the new resolver.
102
+ function setTokenUriResolver(IJBTokenUriResolver resolver) external override onlyOwner {
103
+ // Store the new resolver.
104
+ tokenUriResolver = resolver;
105
+
106
+ emit SetTokenUriResolver({resolver: resolver, caller: _msgSender()});
107
+ }
108
+
109
+ //*********************************************************************//
110
+ // ---------------------- public transactions ---------------------- //
111
+ //*********************************************************************//
112
+
113
+ /// @notice Create a new project for the specified owner, which mints an NFT (ERC-721) into their wallet.
114
+ /// @dev Anyone can create a project on an owner's behalf.
115
+ /// @param owner The address that will be the owner of the project.
116
+ /// @return projectId The token ID of the newly created project.
117
+ function createFor(address owner) public override returns (uint256 projectId) {
118
+ // Increment the count, which will be used as the ID.
119
+ projectId = ++count;
120
+
121
+ emit Create({projectId: projectId, owner: owner, caller: _msgSender()});
122
+
123
+ // Mint the project.
124
+ _safeMint(owner, projectId);
125
+ }
126
+ }