@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,376 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.23;
3
+
4
+ import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
5
+
6
+ import {JBControlled} from "./abstract/JBControlled.sol";
7
+ import {IJBDirectory} from "./interfaces/IJBDirectory.sol";
8
+ import {IJBToken} from "./interfaces/IJBToken.sol";
9
+ import {IJBTokens} from "./interfaces/IJBTokens.sol";
10
+
11
+ /// @notice Manages minting, burning, and balances of projects' tokens and token credits.
12
+ /// @dev Token balances can either be ERC-20s or token credits. This contract manages these two representations and
13
+ /// allows credit -> ERC-20 claiming.
14
+ /// @dev The total supply of a project's tokens and the balance of each account are calculated in this contract.
15
+ /// @dev An ERC-20 contract must be set by a project's owner for ERC-20 claiming to become available. Projects can bring
16
+ /// their own IJBToken if they prefer.
17
+ contract JBTokens is JBControlled, IJBTokens {
18
+ //*********************************************************************//
19
+ // --------------------------- custom errors ------------------------- //
20
+ //*********************************************************************//
21
+
22
+ error JBTokens_EmptyName();
23
+ error JBTokens_EmptySymbol();
24
+ error JBTokens_EmptyToken(uint256 projectId);
25
+ error JBTokens_InsufficientCredits(uint256 count, uint256 creditBalance);
26
+ error JBTokens_InsufficientTokensToBurn(uint256 count, uint256 tokenBalance);
27
+ error JBTokens_OverflowAlert(uint256 value, uint256 limit);
28
+ error JBTokens_ProjectAlreadyHasToken(IJBToken token);
29
+ error JBTokens_TokenAlreadyBeingUsed(uint256 projectId);
30
+ error JBTokens_TokenCantBeAdded(uint256 projectId);
31
+ error JBTokens_TokenNotFound();
32
+ error JBTokens_TokensMustHave18Decimals(uint256 decimals);
33
+
34
+ //*********************************************************************//
35
+ // --------------- public immutable stored properties ---------------- //
36
+ //*********************************************************************//
37
+
38
+ /// @notice A reference to the token implementation that'll be cloned as projects deploy their own tokens.
39
+ IJBToken public immutable TOKEN;
40
+
41
+ //*********************************************************************//
42
+ // --------------------- public stored properties -------------------- //
43
+ //*********************************************************************//
44
+
45
+ /// @notice Each holder's credit balance for each project.
46
+ /// @custom:param holder The credit holder.
47
+ /// @custom:param projectId The ID of the project to which the credits belong.
48
+ mapping(address holder => mapping(uint256 projectId => uint256)) public override creditBalanceOf;
49
+
50
+ /// @notice Each token's project.
51
+ /// @custom:param token The address of the token associated with the project.
52
+ // slither-disable-next-line unused-return
53
+ mapping(IJBToken token => uint256) public override projectIdOf;
54
+
55
+ /// @notice Each project's attached token contract.
56
+ /// @custom:param projectId The ID of the project the token belongs to.
57
+ mapping(uint256 projectId => IJBToken) public override tokenOf;
58
+
59
+ /// @notice The total supply of credits for each project.
60
+ /// @custom:param projectId The ID of the project to which the credits belong.
61
+ mapping(uint256 projectId => uint256) public override totalCreditSupplyOf;
62
+
63
+ //*********************************************************************//
64
+ // -------------------------- constructor ---------------------------- //
65
+ //*********************************************************************//
66
+
67
+ /// @param directory A contract storing directories of terminals and controllers for each project.
68
+ /// @param token The implementation of the token contract that project can deploy.
69
+ constructor(IJBDirectory directory, IJBToken token) JBControlled(directory) {
70
+ TOKEN = token;
71
+ }
72
+
73
+ //*********************************************************************//
74
+ // ------------------------- external views -------------------------- //
75
+ //*********************************************************************//
76
+
77
+ /// @notice The total balance a holder has for a specified project, including both tokens and token credits.
78
+ /// @param holder The holder to get a balance for.
79
+ /// @param projectId The project to get the `holder`'s balance for.
80
+ /// @return balance The combined token and token credit balance of the `holder`.
81
+ function totalBalanceOf(address holder, uint256 projectId) external view override returns (uint256 balance) {
82
+ // Get a reference to the holder's credits for the project.
83
+ balance = creditBalanceOf[holder][projectId];
84
+
85
+ // Get a reference to the project's current token.
86
+ IJBToken token = tokenOf[projectId];
87
+
88
+ // If the project has a current token, add the holder's balance to the total.
89
+ if (token != IJBToken(address(0))) {
90
+ balance += token.balanceOf(holder);
91
+ }
92
+ }
93
+
94
+ //*********************************************************************//
95
+ // --------------------------- public views -------------------------- //
96
+ //*********************************************************************//
97
+
98
+ /// @notice The total supply for a specific project, including both tokens and token credits.
99
+ /// @param projectId The ID of the project to get the total supply of.
100
+ /// @return totalSupply The total supply of the project's tokens and token credits.
101
+ function totalSupplyOf(uint256 projectId) public view override returns (uint256 totalSupply) {
102
+ // Get a reference to the total supply of the project's credits
103
+ totalSupply = totalCreditSupplyOf[projectId];
104
+
105
+ // Get a reference to the project's current token.
106
+ IJBToken token = tokenOf[projectId];
107
+
108
+ // If the project has a current token, add its total supply to the total.
109
+ if (token != IJBToken(address(0))) {
110
+ totalSupply += token.totalSupply();
111
+ }
112
+ }
113
+
114
+ //*********************************************************************//
115
+ // ---------------------- external transactions ---------------------- //
116
+ //*********************************************************************//
117
+
118
+ /// @notice Burns (destroys) credits or tokens.
119
+ /// @dev Credits are burned first, then tokens are burned.
120
+ /// @dev Only a project's current controller can burn its tokens.
121
+ /// @param holder The address that owns the tokens which are being burned.
122
+ /// @param projectId The ID of the project to the burned tokens belong to.
123
+ /// @param count The number of tokens to burn.
124
+ function burnFrom(address holder, uint256 projectId, uint256 count) external override onlyControllerOf(projectId) {
125
+ // Get a reference to the project's current token.
126
+ IJBToken token = tokenOf[projectId];
127
+
128
+ // Get a reference to the amount of credits the holder has.
129
+ uint256 creditBalance = creditBalanceOf[holder][projectId];
130
+
131
+ // Get a reference to the amount of the project's current token the holder has in their wallet.
132
+ uint256 tokenBalance = token == IJBToken(address(0)) ? 0 : token.balanceOf(holder);
133
+
134
+ // There must be enough tokens to burn across the holder's combined token and credit balance.
135
+ if (count > tokenBalance + creditBalance) {
136
+ revert JBTokens_InsufficientTokensToBurn(count, tokenBalance + creditBalance);
137
+ }
138
+
139
+ // The amount of tokens to burn.
140
+ uint256 tokensToBurn;
141
+
142
+ // Get a reference to how many tokens should be burned
143
+ if (tokenBalance != 0) {
144
+ // Burn credits before tokens.
145
+ unchecked {
146
+ tokensToBurn = creditBalance < count ? count - creditBalance : 0;
147
+ }
148
+ }
149
+
150
+ // The amount of credits to burn.
151
+ uint256 creditsToBurn;
152
+ unchecked {
153
+ creditsToBurn = count - tokensToBurn;
154
+ }
155
+
156
+ // Subtract the burned credits from the credit balance and credit supply.
157
+ if (creditsToBurn > 0) {
158
+ creditBalanceOf[holder][projectId] = creditBalanceOf[holder][projectId] - creditsToBurn;
159
+ totalCreditSupplyOf[projectId] = totalCreditSupplyOf[projectId] - creditsToBurn;
160
+ }
161
+
162
+ emit Burn({
163
+ holder: holder,
164
+ projectId: projectId,
165
+ count: count,
166
+ creditBalance: creditBalance,
167
+ tokenBalance: tokenBalance,
168
+ caller: msg.sender
169
+ });
170
+
171
+ // Burn the tokens.
172
+ if (tokensToBurn > 0) token.burn(holder, tokensToBurn);
173
+ }
174
+
175
+ /// @notice Redeem credits to claim tokens into a holder's wallet.
176
+ /// @dev Only a project's controller can claim that project's tokens.
177
+ /// @param holder The owner of the credits being redeemed.
178
+ /// @param projectId The ID of the project whose tokens are being claimed.
179
+ /// @param count The number of tokens to claim.
180
+ /// @param beneficiary The account into which the claimed tokens will go.
181
+ function claimTokensFor(
182
+ address holder,
183
+ uint256 projectId,
184
+ uint256 count,
185
+ address beneficiary
186
+ )
187
+ external
188
+ override
189
+ onlyControllerOf(projectId)
190
+ {
191
+ // Get a reference to the project's current token.
192
+ IJBToken token = tokenOf[projectId];
193
+
194
+ // The project must have a token contract attached.
195
+ if (token == IJBToken(address(0))) revert JBTokens_TokenNotFound();
196
+
197
+ // Get a reference to the amount of credits the holder has.
198
+ uint256 creditBalance = creditBalanceOf[holder][projectId];
199
+
200
+ // There must be enough credits to claim.
201
+ if (count > creditBalance) revert JBTokens_InsufficientCredits(count, creditBalance);
202
+
203
+ unchecked {
204
+ // Subtract the claim amount from the holder's credit balance.
205
+ creditBalanceOf[holder][projectId] = creditBalance - count;
206
+
207
+ // Subtract the claim amount from the project's total credit supply.
208
+ totalCreditSupplyOf[projectId] -= count;
209
+ }
210
+
211
+ emit ClaimTokens({
212
+ holder: holder,
213
+ projectId: projectId,
214
+ creditBalance: creditBalance,
215
+ count: count,
216
+ beneficiary: beneficiary,
217
+ caller: msg.sender
218
+ });
219
+
220
+ // Mint the equivalent amount of the project's token for the holder.
221
+ token.mint(beneficiary, count);
222
+ }
223
+
224
+ /// @notice Deploys an ERC-20 token for a project. It will be used when claiming tokens.
225
+ /// @dev Deploys a project's ERC-20 token contract.
226
+ /// @dev Only a project's controller can deploy its token.
227
+ /// @param projectId The ID of the project to deploy an ERC-20 token for.
228
+ /// @param name The ERC-20's name.
229
+ /// @param symbol The ERC-20's symbol.
230
+ /// @param salt The salt used for ERC-1167 clone deployment. Pass a non-zero salt for deterministic deployment based
231
+ /// on `msg.sender` and the `TOKEN` implementation address.
232
+ /// @return token The address of the token that was deployed.
233
+ function deployERC20For(
234
+ uint256 projectId,
235
+ string calldata name,
236
+ string calldata symbol,
237
+ bytes32 salt
238
+ )
239
+ external
240
+ override
241
+ onlyControllerOf(projectId)
242
+ returns (IJBToken token)
243
+ {
244
+ // There must be a name.
245
+ if (bytes(name).length == 0) revert JBTokens_EmptyName();
246
+
247
+ // There must be a symbol.
248
+ if (bytes(symbol).length == 0) revert JBTokens_EmptySymbol();
249
+
250
+ // The project shouldn't already have a token.
251
+ if (tokenOf[projectId] != IJBToken(address(0))) revert JBTokens_ProjectAlreadyHasToken(tokenOf[projectId]);
252
+
253
+ token = salt == bytes32(0)
254
+ ? IJBToken(Clones.clone(address(TOKEN)))
255
+ : IJBToken(Clones.cloneDeterministic(address(TOKEN), keccak256(abi.encode(msg.sender, salt))));
256
+
257
+ // Store the token contract.
258
+ tokenOf[projectId] = token;
259
+
260
+ // Store the project for the token.
261
+ projectIdOf[token] = projectId;
262
+
263
+ emit DeployERC20({
264
+ projectId: projectId, token: token, name: name, symbol: symbol, salt: salt, caller: msg.sender
265
+ });
266
+
267
+ // Initialize the token.
268
+ token.initialize({name: name, symbol: symbol, owner: address(this)});
269
+ }
270
+
271
+ /// @notice Mint (create) new tokens or credits.
272
+ /// @dev Only a project's current controller can mint its tokens.
273
+ /// @param holder The address receiving the new tokens.
274
+ /// @param projectId The ID of the project to which the tokens belong.
275
+ /// @param count The number of tokens to mint.
276
+ /// @return token The address of the token that was minted, if the project has a token.
277
+ function mintFor(
278
+ address holder,
279
+ uint256 projectId,
280
+ uint256 count
281
+ )
282
+ external
283
+ override
284
+ onlyControllerOf(projectId)
285
+ returns (IJBToken token)
286
+ {
287
+ // Get a reference to the project's current token.
288
+ token = tokenOf[projectId];
289
+
290
+ // Save a reference to whether there a token exists.
291
+ bool tokensWereClaimed = token != IJBToken(address(0));
292
+
293
+ // The total supply after minting can't exceed the maximum value storable in a uint208.
294
+ if (totalSupplyOf(projectId) + count > type(uint208).max) {
295
+ revert JBTokens_OverflowAlert(totalSupplyOf(projectId) + count, type(uint208).max);
296
+ }
297
+
298
+ if (tokensWereClaimed) {
299
+ // If tokens should be claimed, mint tokens into the holder's wallet.
300
+ // slither-disable-next-line reentrancy-events
301
+ token.mint(holder, count);
302
+ } else {
303
+ // Otherwise, add the tokens to their credits and the credit supply.
304
+ creditBalanceOf[holder][projectId] += count;
305
+ totalCreditSupplyOf[projectId] += count;
306
+ }
307
+
308
+ emit Mint({
309
+ holder: holder, projectId: projectId, count: count, tokensWereClaimed: tokensWereClaimed, caller: msg.sender
310
+ });
311
+ }
312
+
313
+ /// @notice Set a project's token if not already set.
314
+ /// @dev Only a project's controller can set its token.
315
+ /// @param projectId The ID of the project to set the token of.
316
+ /// @param token The new token's address.
317
+ function setTokenFor(uint256 projectId, IJBToken token) external override onlyControllerOf(projectId) {
318
+ // Can't set to the zero address.
319
+ if (token == IJBToken(address(0))) revert JBTokens_EmptyToken(projectId);
320
+
321
+ // Can't set a token if the project is already associated with another token.
322
+ if (tokenOf[projectId] != IJBToken(address(0))) revert JBTokens_ProjectAlreadyHasToken(tokenOf[projectId]);
323
+
324
+ // Can't set a token if it's already associated with another project.
325
+ if (projectIdOf[token] != 0) revert JBTokens_TokenAlreadyBeingUsed(projectIdOf[token]);
326
+
327
+ // Can't change to a token that doesn't use 18 decimals.
328
+ if (token.decimals() != 18) revert JBTokens_TokensMustHave18Decimals(token.decimals());
329
+
330
+ // Make sure the token can be added to the project its being added to.
331
+ if (!token.canBeAddedTo(projectId)) revert JBTokens_TokenCantBeAdded(projectId);
332
+
333
+ // Store the new token.
334
+ tokenOf[projectId] = token;
335
+
336
+ // Store the project for the token.
337
+ projectIdOf[token] = projectId;
338
+
339
+ emit SetToken({projectId: projectId, token: token, caller: msg.sender});
340
+ }
341
+
342
+ /// @notice Allows a holder to transfer credits to another account.
343
+ /// @dev Only a project's controller can transfer credits for that project.
344
+ /// @param holder The address to transfer credits from.
345
+ /// @param projectId The ID of the project whose credits are being transferred.
346
+ /// @param recipient The recipient of the credits.
347
+ /// @param count The number of token credits to transfer.
348
+ function transferCreditsFrom(
349
+ address holder,
350
+ uint256 projectId,
351
+ address recipient,
352
+ uint256 count
353
+ )
354
+ external
355
+ override
356
+ onlyControllerOf(projectId)
357
+ {
358
+ // Get a reference to the holder's unclaimed project token balance.
359
+ uint256 creditBalance = creditBalanceOf[holder][projectId];
360
+
361
+ // The holder must have enough unclaimed tokens to transfer.
362
+ if (count > creditBalance) revert JBTokens_InsufficientCredits(count, creditBalance);
363
+
364
+ // Subtract from the holder's unclaimed token balance.
365
+ unchecked {
366
+ creditBalanceOf[holder][projectId] = creditBalance - count;
367
+ }
368
+
369
+ // Add the unclaimed project tokens to the recipient's balance.
370
+ creditBalanceOf[recipient][projectId] += count;
371
+
372
+ emit TransferCredits({
373
+ holder: holder, projectId: projectId, recipient: recipient, count: count, caller: msg.sender
374
+ });
375
+ }
376
+ }
@@ -0,0 +1,48 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IJBControlled} from "./../interfaces/IJBControlled.sol";
5
+ import {IJBDirectory} from "./../interfaces/IJBDirectory.sol";
6
+
7
+ /// @notice Provides a modifier for contracts with functionality that can only be accessed by a project's controller.
8
+ abstract contract JBControlled is IJBControlled {
9
+ //*********************************************************************//
10
+ // --------------------------- custom errors -------------------------- //
11
+ //*********************************************************************//
12
+
13
+ error JBControlled_ControllerUnauthorized(address controller);
14
+
15
+ //*********************************************************************//
16
+ // ---------------------------- modifiers ---------------------------- //
17
+ //*********************************************************************//
18
+
19
+ /// @notice Only allows the controller of the specified project to proceed.
20
+ /// @param projectId The ID of the project.
21
+ modifier onlyControllerOf(uint256 projectId) {
22
+ _onlyControllerOf(projectId);
23
+ _;
24
+ }
25
+
26
+ //*********************************************************************//
27
+ // ---------------- public immutable stored properties --------------- //
28
+ //*********************************************************************//
29
+
30
+ /// @notice The directory of terminals and controllers for projects.
31
+ IJBDirectory public immutable override DIRECTORY;
32
+
33
+ //*********************************************************************//
34
+ // -------------------------- constructor ---------------------------- //
35
+ //*********************************************************************//
36
+
37
+ /// @param directory A contract storing directories of terminals and controllers for each project.
38
+ constructor(IJBDirectory directory) {
39
+ DIRECTORY = directory;
40
+ }
41
+
42
+ /// @notice Only allows the controller of the specified project to proceed.
43
+ function _onlyControllerOf(uint256 projectId) internal view {
44
+ if (address(DIRECTORY.controllerOf(projectId)) != msg.sender) {
45
+ revert JBControlled_ControllerUnauthorized(address(DIRECTORY.controllerOf(projectId)));
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,77 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {Context} from "@openzeppelin/contracts/utils/Context.sol";
5
+
6
+ import {IJBPermissioned} from "./../interfaces/IJBPermissioned.sol";
7
+ import {IJBPermissions} from "./../interfaces/IJBPermissions.sol";
8
+
9
+ /// @notice Modifiers to allow access to transactions based on which permissions the message's sender has.
10
+ abstract contract JBPermissioned is Context, IJBPermissioned {
11
+ //*********************************************************************//
12
+ // --------------------------- custom errors -------------------------- //
13
+ //*********************************************************************//
14
+
15
+ error JBPermissioned_Unauthorized(address account, address sender, uint256 projectId, uint256 permissionId);
16
+
17
+ //*********************************************************************//
18
+ // ---------------- public immutable stored properties --------------- //
19
+ //*********************************************************************//
20
+
21
+ /// @notice A contract storing permissions.
22
+ IJBPermissions public immutable override PERMISSIONS;
23
+
24
+ //*********************************************************************//
25
+ // -------------------------- constructor ---------------------------- //
26
+ //*********************************************************************//
27
+
28
+ /// @param permissions A contract storing permissions.
29
+ constructor(IJBPermissions permissions) {
30
+ PERMISSIONS = permissions;
31
+ }
32
+
33
+ //*********************************************************************//
34
+ // -------------------------- internal views ------------------------- //
35
+ //*********************************************************************//
36
+
37
+ /// @notice Require the message sender to be the account or have the relevant permission.
38
+ /// @param account The account to allow.
39
+ /// @param projectId The project ID to check the permission under.
40
+ /// @param permissionId The required permission ID. The operator must have this permission within the specified
41
+ /// project ID.
42
+ function _requirePermissionFrom(address account, uint256 projectId, uint256 permissionId) internal view {
43
+ address sender = _msgSender();
44
+ if (
45
+ sender != account
46
+ && !PERMISSIONS.hasPermission({
47
+ operator: sender,
48
+ account: account,
49
+ projectId: projectId,
50
+ permissionId: permissionId,
51
+ includeRoot: true,
52
+ includeWildcardProjectId: true
53
+ })
54
+ ) revert JBPermissioned_Unauthorized(account, sender, projectId, permissionId);
55
+ }
56
+
57
+ /// @notice If the 'alsoGrantAccessIf' condition is truthy, proceed. Otherwise, require the message sender to be the
58
+ /// account or
59
+ /// have the relevant permission.
60
+ /// @param account The account to allow.
61
+ /// @param projectId The project ID to check the permission under.
62
+ /// @param permissionId The required permission ID. The operator must have this permission within the specified
63
+ /// project ID.
64
+ /// @param alsoGrantAccessIf An override condition which will allow access regardless of permissions.
65
+ function _requirePermissionAllowingOverrideFrom(
66
+ address account,
67
+ uint256 projectId,
68
+ uint256 permissionId,
69
+ bool alsoGrantAccessIf
70
+ )
71
+ internal
72
+ view
73
+ {
74
+ if (alsoGrantAccessIf) return;
75
+ _requirePermissionFrom({account: account, projectId: projectId, permissionId: permissionId});
76
+ }
77
+ }
@@ -0,0 +1,12 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ /// @notice A ruleset's approval status in a ruleset approval hook.
5
+ enum JBApprovalStatus {
6
+ Empty,
7
+ Upcoming,
8
+ Active,
9
+ ApprovalExpected,
10
+ Approved,
11
+ Failed
12
+ }
@@ -0,0 +1,15 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
5
+
6
+ import {JBAfterCashOutRecordedContext} from "./../structs/JBAfterCashOutRecordedContext.sol";
7
+
8
+ /// @notice Hook called after a terminal's `cashOutTokensOf(...)` logic completes (if passed by the ruleset's data
9
+ /// hook).
10
+ interface IJBCashOutHook is IERC165 {
11
+ /// @notice Called by the terminal after a cash out has been recorded in the terminal store.
12
+ /// @dev Critical business logic should be protected by appropriate access control.
13
+ /// @param context The context passed in by the terminal, as a `JBAfterCashOutRecordedContext` struct.
14
+ function afterCashOutRecordedWith(JBAfterCashOutRecordedContext calldata context) external payable;
15
+ }
@@ -0,0 +1,51 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IJBCashOutHook} from "./IJBCashOutHook.sol";
5
+ import {IJBTerminal} from "./IJBTerminal.sol";
6
+ import {JBAfterCashOutRecordedContext} from "../structs/JBAfterCashOutRecordedContext.sol";
7
+
8
+ /// @notice A terminal that can be cashed out from.
9
+ interface IJBCashOutTerminal is IJBTerminal {
10
+ event HookAfterRecordCashOut(
11
+ IJBCashOutHook indexed hook,
12
+ JBAfterCashOutRecordedContext context,
13
+ uint256 specificationAmount,
14
+ uint256 fee,
15
+ address caller
16
+ );
17
+ event CashOutTokens(
18
+ uint256 indexed rulesetId,
19
+ uint256 indexed rulesetCycleNumber,
20
+ uint256 indexed projectId,
21
+ address holder,
22
+ address beneficiary,
23
+ uint256 cashOutCount,
24
+ uint256 cashOutTaxRate,
25
+ uint256 reclaimAmount,
26
+ bytes metadata,
27
+ address caller
28
+ );
29
+
30
+ /// @notice Cashes out a holder's tokens for a project, reclaiming the token's proportional share of the project's
31
+ /// surplus.
32
+ /// @param holder The address whose tokens are being cashed out.
33
+ /// @param projectId The ID of the project whose tokens are being cashed out.
34
+ /// @param cashOutCount The number of project tokens to cash out.
35
+ /// @param tokenToReclaim The token to reclaim from the project's surplus.
36
+ /// @param minTokensReclaimed The minimum number of terminal tokens expected to be reclaimed.
37
+ /// @param beneficiary The address to send the reclaimed tokens to.
38
+ /// @param metadata Extra data to send to the data hook and cash out hooks.
39
+ /// @return reclaimAmount The amount of tokens reclaimed from the project's surplus.
40
+ function cashOutTokensOf(
41
+ address holder,
42
+ uint256 projectId,
43
+ uint256 cashOutCount,
44
+ address tokenToReclaim,
45
+ uint256 minTokensReclaimed,
46
+ address payable beneficiary,
47
+ bytes calldata metadata
48
+ )
49
+ external
50
+ returns (uint256 reclaimAmount);
51
+ }
@@ -0,0 +1,10 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IJBDirectory} from "./IJBDirectory.sol";
5
+
6
+ /// @notice A contract that is controlled by a project's controller via the directory.
7
+ interface IJBControlled {
8
+ /// @notice The directory of terminals and controllers for projects.
9
+ function DIRECTORY() external view returns (IJBDirectory);
10
+ }