@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,1001 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.6;
3
+
4
+ import /* {*} from */ "./helpers/TestBaseWorkflow.sol";
5
+
6
+ // A project's rulesets can be queued, and re-queued as long as the current ruleset approval hook approves.
7
+ contract TestRulesetQueuing_Local is TestBaseWorkflow {
8
+ IJBController private _controller;
9
+ JBRulesetMetadata private _metadata;
10
+ JBDeadline private _deadline;
11
+ JBSplitGroup[] private _splitGroup;
12
+ JBFundAccessLimitGroup[] private _fundAccessLimitGroup;
13
+ IJBTerminal private _terminal;
14
+ uint112 private _weight;
15
+
16
+ uint256 private _DEADLINE_DURATION = 3 days;
17
+ uint256 private _RULESET_DURATION_DAYS = 6;
18
+ uint32 private _RULESET_DURATION = uint32(_RULESET_DURATION_DAYS * 1 days);
19
+
20
+ function setUp() public override {
21
+ super.setUp();
22
+
23
+ _terminal = jbMultiTerminal();
24
+ _controller = jbController();
25
+
26
+ _deadline = new JBDeadline(_DEADLINE_DURATION);
27
+ _weight = 1000 * 10 ** 18;
28
+
29
+ _metadata = JBRulesetMetadata({
30
+ reservedPercent: 0,
31
+ cashOutTaxRate: 0,
32
+ baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
33
+ pausePay: false,
34
+ pauseCreditTransfers: false,
35
+ allowOwnerMinting: false,
36
+ allowSetCustomToken: false,
37
+ allowTerminalMigration: false,
38
+ allowSetTerminals: false,
39
+ ownerMustSendPayouts: false,
40
+ allowSetController: false,
41
+ allowAddAccountingContext: true,
42
+ allowAddPriceFeed: false,
43
+ holdFees: false,
44
+ useTotalSurplusForCashOuts: false,
45
+ useDataHookForPay: false,
46
+ useDataHookForCashOut: false,
47
+ dataHook: address(0),
48
+ metadata: 0
49
+ });
50
+ }
51
+
52
+ function launchProjectForTest() public returns (uint256) {
53
+ // Package up ruleset configuration.
54
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](1);
55
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
56
+ _rulesetConfig[0].duration = _RULESET_DURATION;
57
+ _rulesetConfig[0].weight = _weight;
58
+ _rulesetConfig[0].weightCutPercent = 0;
59
+ _rulesetConfig[0].approvalHook = _deadline;
60
+ _rulesetConfig[0].metadata = _metadata;
61
+ _rulesetConfig[0].splitGroups = new JBSplitGroup[](0);
62
+ _rulesetConfig[0].fundAccessLimitGroups = new JBFundAccessLimitGroup[](0);
63
+
64
+ // Package up terminal configuration.
65
+ JBTerminalConfig[] memory _terminalConfigurations = new JBTerminalConfig[](1);
66
+ JBAccountingContext[] memory _tokensToAccept = new JBAccountingContext[](1);
67
+ _tokensToAccept[0] = JBAccountingContext({
68
+ token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
69
+ });
70
+ _terminalConfigurations[0] =
71
+ JBTerminalConfig({terminal: _terminal, accountingContextsToAccept: _tokensToAccept});
72
+
73
+ uint256 projectId = _controller.launchProjectFor({
74
+ owner: address(multisig()),
75
+ projectUri: "myIPFSHash",
76
+ rulesetConfigurations: _rulesetConfig,
77
+ terminalConfigurations: _terminalConfigurations,
78
+ memo: ""
79
+ });
80
+
81
+ return projectId;
82
+ }
83
+
84
+ function launchProjectForTestWithThreeRulesets() public returns (uint256) {
85
+ // Package up ruleset configuration.
86
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](3);
87
+
88
+ // first ruleset
89
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
90
+ _rulesetConfig[0].duration = 1 days;
91
+ _rulesetConfig[0].weight = _weight;
92
+ _rulesetConfig[0].weightCutPercent = 0;
93
+ _rulesetConfig[0].approvalHook = IJBRulesetApprovalHook(address(0));
94
+ _rulesetConfig[0].metadata = _metadata;
95
+ _rulesetConfig[0].splitGroups = new JBSplitGroup[](0);
96
+ _rulesetConfig[0].fundAccessLimitGroups = new JBFundAccessLimitGroup[](0);
97
+
98
+ // second
99
+ _rulesetConfig[1].mustStartAtOrAfter = uint48(block.timestamp + 1 days);
100
+ _rulesetConfig[1].duration = 1 days;
101
+ _rulesetConfig[1].weight = _weight + 100;
102
+ _rulesetConfig[1].weightCutPercent = 0;
103
+ _rulesetConfig[1].approvalHook = IJBRulesetApprovalHook(address(0));
104
+ _rulesetConfig[1].metadata = _metadata;
105
+ _rulesetConfig[1].splitGroups = new JBSplitGroup[](0);
106
+ _rulesetConfig[1].fundAccessLimitGroups = new JBFundAccessLimitGroup[](0);
107
+
108
+ // third
109
+ _rulesetConfig[2].mustStartAtOrAfter = uint48(block.timestamp + 2 days);
110
+ _rulesetConfig[2].duration = 1 days;
111
+ _rulesetConfig[2].weight = _weight + 200;
112
+ _rulesetConfig[2].weightCutPercent = 0;
113
+ _rulesetConfig[2].approvalHook = IJBRulesetApprovalHook(address(0));
114
+ _rulesetConfig[2].metadata = _metadata;
115
+ _rulesetConfig[2].splitGroups = new JBSplitGroup[](0);
116
+ _rulesetConfig[2].fundAccessLimitGroups = new JBFundAccessLimitGroup[](0);
117
+
118
+ // Package up terminal configuration.
119
+ JBTerminalConfig[] memory _terminalConfigurations = new JBTerminalConfig[](1);
120
+ JBAccountingContext[] memory _tokensToAccept = new JBAccountingContext[](1);
121
+ _tokensToAccept[0] = JBAccountingContext({
122
+ token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
123
+ });
124
+ _terminalConfigurations[0] =
125
+ JBTerminalConfig({terminal: _terminal, accountingContextsToAccept: _tokensToAccept});
126
+
127
+ uint256 projectId = _controller.launchProjectFor({
128
+ owner: address(multisig()),
129
+ projectUri: "myIPFSHash",
130
+ rulesetConfigurations: _rulesetConfig,
131
+ terminalConfigurations: _terminalConfigurations,
132
+ memo: ""
133
+ });
134
+
135
+ return projectId;
136
+ }
137
+
138
+ function testEmptyConfig() public {
139
+ // it will revert with JBController_RulesetsArrayEmpty
140
+
141
+ // length of zero should revert
142
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](0);
143
+
144
+ // Deploy a project.
145
+ uint256 projectId = launchProjectForTest();
146
+
147
+ vm.expectRevert(JBController.JBController_RulesetsArrayEmpty.selector);
148
+
149
+ // call
150
+ vm.prank(multisig());
151
+ _controller.queueRulesetsOf(projectId, _rulesetConfig, "");
152
+ }
153
+
154
+ function testReconfigureProject() public {
155
+ // Package a ruleset configuration.
156
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](1);
157
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
158
+ _rulesetConfig[0].duration = _RULESET_DURATION;
159
+ _rulesetConfig[0].weight = _weight;
160
+ _rulesetConfig[0].weightCutPercent = 0;
161
+ _rulesetConfig[0].approvalHook = _deadline;
162
+ _rulesetConfig[0].metadata = _metadata;
163
+ _rulesetConfig[0].splitGroups = _splitGroup;
164
+ _rulesetConfig[0].fundAccessLimitGroups = _fundAccessLimitGroup;
165
+
166
+ // Deploy a project.
167
+ uint256 projectId = launchProjectForTest();
168
+
169
+ // Keep a reference to the current ruleset.
170
+ JBRuleset memory _ruleset = jbRulesets().currentOf(projectId);
171
+
172
+ // Make sure the ruleset has a cycle number of 1.
173
+ assertEq(_ruleset.cycleNumber, 1);
174
+ // Make sure the ruleset's weight matches.
175
+ assertEq(_ruleset.weight, _weight);
176
+
177
+ // Keep a reference to the ruleset's ID.
178
+ uint256 _currentRulesetId = _ruleset.id;
179
+
180
+ // Increment the weight to create a difference.
181
+ _rulesetConfig[0].weight = _rulesetConfig[0].weight + 1;
182
+
183
+ // Add a ruleset.
184
+ vm.prank(multisig());
185
+ _controller.queueRulesetsOf(projectId, _rulesetConfig, "");
186
+
187
+ // Make sure the current ruleset hasn't changed.
188
+ _ruleset = jbRulesets().currentOf(projectId);
189
+ assertEq(_ruleset.cycleNumber, 1);
190
+ assertEq(_ruleset.id, _currentRulesetId);
191
+ assertEq(_ruleset.weight, _weight);
192
+
193
+ // Go to the start of the next ruleset.
194
+ vm.warp(_ruleset.start + _ruleset.duration);
195
+
196
+ // Get the current ruleset.
197
+ JBRuleset memory _newRuleset = jbRulesets().currentOf(projectId);
198
+ // It should be the second cycle.
199
+ assertEq(_newRuleset.cycleNumber, 2);
200
+ assertEq(_newRuleset.weight, _weight + 1);
201
+ assertEq(_newRuleset.basedOnId, _currentRulesetId);
202
+ }
203
+
204
+ function testReconfigureProjectWithWeightOfZero() public {
205
+ // Package a ruleset configuration.
206
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](1);
207
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
208
+ _rulesetConfig[0].duration = _RULESET_DURATION;
209
+ _rulesetConfig[0].weightCutPercent = 0;
210
+ _rulesetConfig[0].approvalHook = _deadline;
211
+ _rulesetConfig[0].metadata = _metadata;
212
+ _rulesetConfig[0].splitGroups = _splitGroup;
213
+ _rulesetConfig[0].fundAccessLimitGroups = _fundAccessLimitGroup;
214
+
215
+ // Deploy a project.
216
+ uint256 projectId = launchProjectForTest();
217
+
218
+ // Keep a reference to the current ruleset.
219
+ JBRuleset memory _ruleset = jbRulesets().currentOf(projectId);
220
+
221
+ // Make sure the ruleset has a cycle number of 1.
222
+ assertEq(_ruleset.cycleNumber, 1);
223
+ // Make sure the ruleset's weight matches.
224
+ assertEq(_ruleset.weight, _weight);
225
+
226
+ // Keep a reference to the ruleset's ID.
227
+ uint256 _currentRulesetId = _ruleset.id;
228
+
229
+ // Increment the weight to create a difference.
230
+ _rulesetConfig[0].weight = 0;
231
+
232
+ // Add a ruleset.
233
+ vm.prank(multisig());
234
+ _controller.queueRulesetsOf(projectId, _rulesetConfig, "");
235
+
236
+ // Make sure the current ruleset hasn't changed.
237
+ _ruleset = jbRulesets().currentOf(projectId);
238
+ assertEq(_ruleset.cycleNumber, 1);
239
+ assertEq(_ruleset.id, _currentRulesetId);
240
+ assertEq(_ruleset.weight, _weight);
241
+
242
+ // Go to the start of the next ruleset.
243
+ vm.warp(_ruleset.start + _ruleset.duration);
244
+
245
+ // Get the current ruleset.
246
+ JBRuleset memory _newRuleset = jbRulesets().currentOf(projectId);
247
+
248
+ // It should be the second cycle.
249
+ assertEq(_newRuleset.cycleNumber, 2);
250
+ assertEq(_newRuleset.weight, 0);
251
+ assertEq(_newRuleset.basedOnId, _currentRulesetId);
252
+ }
253
+
254
+ function testReconfigureProjectWithWeightOfOne() public {
255
+ // Package a ruleset configuration.
256
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](1);
257
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
258
+ _rulesetConfig[0].duration = _RULESET_DURATION;
259
+ _rulesetConfig[0].weightCutPercent = 0;
260
+ _rulesetConfig[0].approvalHook = _deadline;
261
+ _rulesetConfig[0].metadata = _metadata;
262
+ _rulesetConfig[0].splitGroups = _splitGroup;
263
+ _rulesetConfig[0].fundAccessLimitGroups = _fundAccessLimitGroup;
264
+
265
+ // Deploy a project.
266
+ uint256 projectId = launchProjectForTest();
267
+
268
+ // Keep a reference to the current ruleset.
269
+ JBRuleset memory _ruleset = jbRulesets().currentOf(projectId);
270
+
271
+ // Make sure the ruleset has a cycle number of 1.
272
+ assertEq(_ruleset.cycleNumber, 1);
273
+ // Make sure the ruleset's weight matches.
274
+ assertEq(_ruleset.weight, _weight);
275
+
276
+ // Keep a reference to the ruleset's ID.
277
+ uint256 _currentRulesetId = _ruleset.id;
278
+
279
+ // Increment the weight to create a difference.
280
+ _rulesetConfig[0].weight = 1;
281
+ _rulesetConfig[0].weightCutPercent = 1_000_000_000 / 2;
282
+ _rulesetConfig[0].duration = 1 days;
283
+
284
+ // Add a ruleset.
285
+ vm.prank(multisig());
286
+ _controller.queueRulesetsOf(projectId, _rulesetConfig, "");
287
+
288
+ // Make sure the current ruleset hasn't changed.
289
+ _ruleset = jbRulesets().currentOf(projectId);
290
+ assertEq(_ruleset.cycleNumber, 1);
291
+ assertEq(_ruleset.id, _currentRulesetId);
292
+ assertEq(_ruleset.weight, _weight);
293
+ assertEq(_ruleset.weightCutPercent, 0);
294
+
295
+ // Go to the start of the next ruleset.
296
+ vm.warp(_ruleset.start + _ruleset.duration + 1 days);
297
+
298
+ // Get the current ruleset.
299
+ JBRuleset memory _newRuleset = jbRulesets().currentOf(projectId);
300
+
301
+ // It should be the second cycle.
302
+ assertEq(_newRuleset.cycleNumber, 3);
303
+ assertEq(_newRuleset.weight, _weight / 2);
304
+ assertEq(_newRuleset.basedOnId, _currentRulesetId);
305
+ }
306
+
307
+ function testMultipleQueuedOnCycledOver() public {
308
+ // Keep references to two different weights.
309
+ uint112 _weightFirstQueued = uint112(1234 * 10 ** 18);
310
+ uint112 _weightSecondQueued = uint112(6969 * 10 ** 18);
311
+
312
+ // Launch a project.
313
+ uint256 projectId = launchProjectForTest();
314
+
315
+ // Keep a reference to the current ruleset.
316
+ JBRuleset memory _ruleset = jbRulesets().currentOf(projectId);
317
+
318
+ // Make sure the ruleset is correct.
319
+ assertEq(_ruleset.cycleNumber, 1);
320
+ assertEq(_ruleset.weight, _weight);
321
+
322
+ // Keep a reference to the current ruleset ID.
323
+ uint256 _currentRulesetId = _ruleset.id;
324
+
325
+ // Jump to the next ruleset.
326
+ vm.warp(block.timestamp + _ruleset.duration);
327
+
328
+ // Package up a first ruleset configuration to queue.
329
+ JBRulesetConfig[] memory _firstQueued = new JBRulesetConfig[](1);
330
+ _firstQueued[0].mustStartAtOrAfter = 0;
331
+ _firstQueued[0].duration = _RULESET_DURATION;
332
+ _firstQueued[0].weight = _weightFirstQueued;
333
+ _firstQueued[0].weightCutPercent = 0;
334
+ _firstQueued[0].approvalHook = _deadline; // 3 day deadline duration.
335
+ _firstQueued[0].metadata = _metadata;
336
+ _firstQueued[0].splitGroups = _splitGroup;
337
+ _firstQueued[0].fundAccessLimitGroups = _fundAccessLimitGroup;
338
+
339
+ // Queue.
340
+ vm.prank(multisig());
341
+ _controller.queueRulesetsOf(projectId, _firstQueued, "");
342
+
343
+ // Package up another ruleset configuration to queue.
344
+ JBRulesetConfig[] memory _secondQueued = new JBRulesetConfig[](1);
345
+ _secondQueued[0].mustStartAtOrAfter = 0;
346
+ _secondQueued[0].duration = _RULESET_DURATION;
347
+ _secondQueued[0].weight = _weightSecondQueued;
348
+ _secondQueued[0].weightCutPercent = 0;
349
+ _secondQueued[0].approvalHook = _deadline; // 3 day deadline duration.
350
+ _secondQueued[0].metadata = _metadata;
351
+ _secondQueued[0].splitGroups = _splitGroup;
352
+ _secondQueued[0].fundAccessLimitGroups = _fundAccessLimitGroup;
353
+
354
+ // Queue again
355
+ vm.prank(multisig());
356
+ _controller.queueRulesetsOf(projectId, _secondQueued, "");
357
+
358
+ // Since the second ruleset was queued during the same block as the one prior, increment the ruleset ID.
359
+ uint256 secondRulesetId = block.timestamp + 1;
360
+
361
+ // The current ruleset should not have changed, still in ruleset #2, cycled over from ruleset #1.
362
+ _ruleset = jbRulesets().currentOf(projectId);
363
+ assertEq(_ruleset.cycleNumber, 2);
364
+ assertEq(_ruleset.id, _currentRulesetId);
365
+ assertEq(_ruleset.weight, _weight);
366
+
367
+ // Jump to after the deadline has passed, but before the next ruleset.
368
+ vm.warp(_ruleset.start + _ruleset.duration - 1);
369
+
370
+ // Make sure the queued ruleset is the second one queued.
371
+ JBRuleset memory queuedRuleset = jbRulesets().upcomingOf(projectId);
372
+ assertEq(queuedRuleset.cycleNumber, 3);
373
+ assertEq(queuedRuleset.id, secondRulesetId);
374
+ assertEq(queuedRuleset.weight, _weightSecondQueued);
375
+
376
+ // Go the the start of the queued ruleset.
377
+ vm.warp(_ruleset.start + _ruleset.duration);
378
+
379
+ // Make sure the second queued is now the current ruleset.
380
+ JBRuleset memory _newRuleset = jbRulesets().currentOf(projectId);
381
+ assertEq(_newRuleset.cycleNumber, 3);
382
+ assertEq(_newRuleset.id, secondRulesetId);
383
+ assertEq(_newRuleset.weight, _weightSecondQueued);
384
+ }
385
+
386
+ function testMultipleReconfigure(uint8 _deadlineDuration) public {
387
+ // Create a deadline with the provided deadline duration.
388
+ _deadline = new JBDeadline(_deadlineDuration);
389
+
390
+ // Package the ruleset data.
391
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](1);
392
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
393
+ _rulesetConfig[0].duration = _RULESET_DURATION;
394
+ _rulesetConfig[0].weight = 10_000 ether;
395
+ _rulesetConfig[0].weightCutPercent = 0;
396
+ _rulesetConfig[0].approvalHook = _deadline;
397
+ _rulesetConfig[0].metadata = _metadata;
398
+ _rulesetConfig[0].splitGroups = _splitGroup;
399
+ _rulesetConfig[0].fundAccessLimitGroups = _fundAccessLimitGroup;
400
+
401
+ // Launch a project to test.
402
+ uint256 projectId = launchProjectForTest();
403
+
404
+ // Keep a reference to the initial, current, and queued rulesets.
405
+ JBRuleset memory initialRuleset = jbRulesets().currentOf(projectId);
406
+ JBRuleset memory currentRuleset = initialRuleset;
407
+ JBRuleset memory upcomingRuleset = jbRulesets().upcomingOf(projectId);
408
+
409
+ for (uint256 i = 0; i < _RULESET_DURATION_DAYS + 1; i++) {
410
+ // If the deadline is less than the ruleset's duration, make sure the current ruleset's weight is linearly
411
+ // decremented.
412
+ if (_deadlineDuration + i * 1 days < currentRuleset.duration) {
413
+ assertEq(currentRuleset.weight, initialRuleset.weight - i);
414
+ }
415
+
416
+ JBRulesetConfig[] memory _config = new JBRulesetConfig[](1);
417
+ _config[0].mustStartAtOrAfter = 0;
418
+ _config[0].duration = _RULESET_DURATION;
419
+ // Package up a new ruleset with a decremented weight.
420
+ _config[0].weight = uint112(initialRuleset.weight - (i + 1)); // i+1 -> next ruleset
421
+ _config[0].weightCutPercent = 0;
422
+ _config[0].approvalHook = _deadline;
423
+ _config[0].metadata = _metadata;
424
+ _config[0].splitGroups = _splitGroup;
425
+ _config[0].fundAccessLimitGroups = _fundAccessLimitGroup;
426
+
427
+ // Queue the ruleset.
428
+ vm.prank(multisig());
429
+ _controller.queueRulesetsOf(projectId, _config, "");
430
+
431
+ // Get a reference to the current and upcoming rulesets.
432
+ currentRuleset = jbRulesets().currentOf(projectId);
433
+ upcomingRuleset = jbRulesets().upcomingOf(projectId);
434
+
435
+ // Get a list of queued rulesets
436
+ JBRuleset[] memory rulesetsOf = jbRulesets().allOf(projectId, 0, 1);
437
+
438
+ // Make sure the upcoming ruleset is the ruleset currently under the approval hook.
439
+ assertEq(upcomingRuleset.weight, _config[0].weight);
440
+ assertEq(rulesetsOf[0].weight, _config[0].weight);
441
+
442
+ // If the full deadline duration included in the ruleset.
443
+ if (
444
+ _deadlineDuration == 0
445
+ || currentRuleset.duration % (_deadlineDuration + i * 1 days) < currentRuleset.duration
446
+ ) {
447
+ // Make sure the current ruleset's weight is still linearly decremented.
448
+ assertEq(currentRuleset.weight, initialRuleset.weight - i);
449
+
450
+ // Shift forward the start of the deadline into the ruleset, one day at a time, from ruleset to ruleset.
451
+ vm.warp(currentRuleset.start + currentRuleset.duration + i * 1 days);
452
+
453
+ // Make sure what was the upcoming ruleset is now current.
454
+ currentRuleset = jbRulesets().currentOf(projectId);
455
+ assertEq(currentRuleset.weight, _config[0].weight);
456
+
457
+ // Make the upcoming is the cycled over version of current.
458
+ upcomingRuleset = jbRulesets().upcomingOf(projectId);
459
+ assertEq(upcomingRuleset.weight, _config[0].weight);
460
+ }
461
+ // If the deadline duration is across many rulesets.
462
+ else {
463
+ // Make sure the current ruleset has cycled over.
464
+ vm.warp(currentRuleset.start + currentRuleset.duration);
465
+ assertEq(currentRuleset.weight, initialRuleset.weight - i);
466
+
467
+ // Make sure the new ruleset has started once the deadline duration has passed.
468
+ vm.warp(currentRuleset.start + currentRuleset.duration + _deadlineDuration);
469
+ currentRuleset = jbRulesets().currentOf(projectId);
470
+ assertEq(currentRuleset.weight, _config[0].weight);
471
+ }
472
+ }
473
+ }
474
+
475
+ function testLaunchProjectWrongApprovalHook() public {
476
+ /// Package the configuration.
477
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](1);
478
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
479
+ _rulesetConfig[0].duration = 0;
480
+ _rulesetConfig[0].weight = _weight;
481
+ _rulesetConfig[0].weightCutPercent = 0;
482
+ _rulesetConfig[0].approvalHook = IJBRulesetApprovalHook(address(0));
483
+ _rulesetConfig[0].metadata = _metadata;
484
+ _rulesetConfig[0].splitGroups = _splitGroup;
485
+ _rulesetConfig[0].fundAccessLimitGroups = _fundAccessLimitGroup;
486
+
487
+ // Launch the project.
488
+ uint256 projectId = launchProjectForTest();
489
+
490
+ IJBRulesetApprovalHook invalidHook = IJBRulesetApprovalHook(address(6969));
491
+
492
+ vm.prank(multisig());
493
+ vm.expectRevert(abi.encodeWithSelector(JBRulesets.JBRulesets_InvalidRulesetApprovalHook.selector, invalidHook));
494
+
495
+ JBRulesetConfig[] memory _config = new JBRulesetConfig[](1);
496
+ _config[0].mustStartAtOrAfter = 0;
497
+ _config[0].duration = _RULESET_DURATION;
498
+ _config[0].weight = 12_345 * 10 ** 18;
499
+ _config[0].weightCutPercent = 0;
500
+ _config[0].approvalHook = invalidHook;
501
+ _config[0].metadata = _metadata;
502
+ _config[0].splitGroups = _splitGroup;
503
+ _config[0].fundAccessLimitGroups = _fundAccessLimitGroup;
504
+
505
+ _controller.queueRulesetsOf(projectId, _config, "");
506
+ }
507
+
508
+ function testQueueShortDurationProject() public {
509
+ uint32 _shortDuration = 5 minutes;
510
+
511
+ _weight = uint112(10_000 * 10 ** 18);
512
+ _RULESET_DURATION = _shortDuration;
513
+
514
+ // Launch a project to test.
515
+ uint256 projectId = launchProjectForTest();
516
+
517
+ // Get a reference to the current ruleset.
518
+ JBRuleset memory _ruleset = jbRulesets().currentOf(projectId);
519
+
520
+ // Make sure the current ruleset is correct.
521
+ assertEq(_ruleset.cycleNumber, 1); // Ok.
522
+ assertEq(_ruleset.weight, _weight);
523
+
524
+ // Keep a reference to the current ruleset ID.
525
+ uint256 _currentRulesetId = _ruleset.id;
526
+
527
+ // Package up a reconfiguration.
528
+ JBRulesetConfig[] memory _config = new JBRulesetConfig[](1);
529
+ _config[0].mustStartAtOrAfter = 0;
530
+ _config[0].duration = _RULESET_DURATION;
531
+ _config[0].weight = 69 * 10 ** 18;
532
+ _config[0].weightCutPercent = 0;
533
+ _config[0].approvalHook = IJBRulesetApprovalHook(address(0));
534
+ _config[0].metadata = _metadata;
535
+ _config[0].splitGroups = _splitGroup;
536
+ _config[0].fundAccessLimitGroups = _fundAccessLimitGroup;
537
+
538
+ // Submit the reconfiguration.
539
+ vm.prank(multisig());
540
+ _controller.queueRulesetsOf(projectId, _config, "");
541
+
542
+ // Make sure the ruleset hasn't changed.
543
+ _ruleset = jbRulesets().currentOf(projectId);
544
+ assertEq(_ruleset.cycleNumber, 1);
545
+ assertEq(_ruleset.id, _currentRulesetId);
546
+ assertEq(_ruleset.weight, _weight);
547
+
548
+ // Go the the second ruleset.
549
+ vm.warp(_ruleset.start + _ruleset.duration);
550
+
551
+ // Make sure the ruleset cycled over.
552
+ JBRuleset memory _newRuleset = jbRulesets().currentOf(projectId);
553
+ assertEq(_newRuleset.cycleNumber, 2);
554
+ assertEq(_newRuleset.weight, _weight);
555
+
556
+ // Go to the end of the deadline duration.
557
+ vm.warp(_ruleset.start + _ruleset.duration + _DEADLINE_DURATION);
558
+
559
+ // Make sure the queued cycle is in effect.
560
+ _newRuleset = jbRulesets().currentOf(projectId);
561
+ assertEq(_newRuleset.cycleNumber, _ruleset.cycleNumber + (_DEADLINE_DURATION / _shortDuration) + 1);
562
+ assertEq(_newRuleset.weight, _config[0].weight);
563
+ }
564
+
565
+ function testQueueWithoutApprovalHook() public {
566
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](1);
567
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
568
+ _rulesetConfig[0].duration = 5 minutes;
569
+ _rulesetConfig[0].weight = 10_000 * 10 ** 18;
570
+ _rulesetConfig[0].weightCutPercent = 0;
571
+ _rulesetConfig[0].approvalHook = IJBRulesetApprovalHook(address(0));
572
+ _rulesetConfig[0].metadata = _metadata;
573
+ _rulesetConfig[0].splitGroups = _splitGroup;
574
+ _rulesetConfig[0].fundAccessLimitGroups = _fundAccessLimitGroup;
575
+
576
+ // Launch a project to test with.
577
+ uint256 projectId = launchProjectForTest();
578
+
579
+ // Get a reference to the current ruleset.
580
+ JBRuleset memory _ruleset = jbRulesets().currentOf(projectId);
581
+
582
+ // Make sure the ruleset is expected.
583
+ assertEq(_ruleset.cycleNumber, 1);
584
+ assertEq(_ruleset.weight, _weight);
585
+
586
+ // Package a new config.
587
+ JBRulesetConfig[] memory _config = new JBRulesetConfig[](1);
588
+
589
+ _config[0].mustStartAtOrAfter = 0;
590
+ _config[0].duration = _RULESET_DURATION;
591
+ _config[0].weight = 69 * 10 ** 18;
592
+ _config[0].weightCutPercent = 0;
593
+ _config[0].approvalHook = IJBRulesetApprovalHook(address(0));
594
+ _config[0].metadata = _metadata;
595
+ _config[0].splitGroups = _splitGroup;
596
+ _config[0].fundAccessLimitGroups = _fundAccessLimitGroup;
597
+
598
+ vm.prank(multisig());
599
+ _controller.queueRulesetsOf(projectId, _config, "");
600
+
601
+ // Make sure the ruleset hasn't changed.
602
+ _ruleset = jbRulesets().currentOf(projectId);
603
+ assertEq(_ruleset.cycleNumber, 1);
604
+ assertEq(_ruleset.weight, _weight);
605
+
606
+ // Make sure the ruleset has changed once the ruleset is over.
607
+ vm.warp(_ruleset.start + _ruleset.duration);
608
+ _ruleset = jbRulesets().currentOf(projectId);
609
+ assertEq(_ruleset.cycleNumber, 2);
610
+ assertEq(_ruleset.weight, 69 * 10 ** 18);
611
+ }
612
+
613
+ function testMixedStarts() public {
614
+ // Keep references to our different weights for assertions.
615
+ uint112 _weightInitial = uint112(1000 * 10 ** 18);
616
+ uint112 _weightFirstQueued = uint112(1234 * 10 ** 18);
617
+ uint112 _weightSecondQueued = uint112(6969 * 10 ** 18);
618
+
619
+ // Keep a reference to the expected ruleset IDs (timestamps).
620
+ uint256 _initialRulesetId = block.timestamp;
621
+
622
+ // Package up a config.
623
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](1);
624
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
625
+ _rulesetConfig[0].duration = _RULESET_DURATION;
626
+ _rulesetConfig[0].weight = _weightInitial;
627
+ _rulesetConfig[0].weightCutPercent = 0;
628
+ _rulesetConfig[0].approvalHook = _deadline; // day deadline duration.
629
+ _rulesetConfig[0].metadata = _metadata;
630
+ _rulesetConfig[0].splitGroups = _splitGroup;
631
+ _rulesetConfig[0].fundAccessLimitGroups = _fundAccessLimitGroup;
632
+
633
+ // Launch the project to test with.
634
+ uint256 projectId = launchProjectForTest();
635
+
636
+ // Get the ruleset.
637
+ JBRuleset memory _ruleset = jbRulesets().currentOf(projectId);
638
+
639
+ // Make sure the first ruleset has begun.
640
+ assertEq(_ruleset.cycleNumber, 1);
641
+ assertEq(_ruleset.weight, _weightInitial);
642
+ assertEq(_ruleset.id, block.timestamp);
643
+
644
+ // Package up a new config.
645
+ JBRulesetConfig[] memory _firstQueued = new JBRulesetConfig[](1);
646
+ _firstQueued[0].mustStartAtOrAfter = 0;
647
+ _firstQueued[0].duration = _RULESET_DURATION;
648
+ _firstQueued[0].weight = _weightFirstQueued;
649
+ _firstQueued[0].weightCutPercent = 0;
650
+ _firstQueued[0].approvalHook = _deadline; // 3 day deadline duration.
651
+ _firstQueued[0].metadata = _metadata;
652
+ _firstQueued[0].splitGroups = _splitGroup;
653
+ _firstQueued[0].fundAccessLimitGroups = _fundAccessLimitGroup;
654
+
655
+ // Queue a ruleset to be overridden (will be in `ApprovalExpected` status of the approval hook).
656
+ vm.prank(multisig());
657
+ _controller.queueRulesetsOf(projectId, _firstQueued, "");
658
+
659
+ // Make sure the ruleset is queued.
660
+ JBRuleset memory _queued = jbRulesets().upcomingOf(projectId);
661
+ assertEq(_queued.cycleNumber, 2);
662
+ assertEq(_queued.id, _initialRulesetId + 1);
663
+ assertEq(_queued.weight, _weightFirstQueued);
664
+
665
+ // Get a list of queued rulesets
666
+ JBRuleset[] memory queuedRulesets = jbRulesets().allOf(projectId, 0, 1);
667
+
668
+ // Ensure rulesetsOf is accurate
669
+ assertEq(queuedRulesets[0].weight, _weightFirstQueued);
670
+
671
+ // Package up another config.
672
+ JBRulesetConfig[] memory _secondQueued = new JBRulesetConfig[](1);
673
+ _secondQueued[0].mustStartAtOrAfter = uint48(block.timestamp + 9 days);
674
+ _secondQueued[0].duration = _RULESET_DURATION;
675
+ _secondQueued[0].weight = _weightSecondQueued;
676
+ _secondQueued[0].weightCutPercent = 0;
677
+ _secondQueued[0].approvalHook = _deadline;
678
+ _secondQueued[0].metadata = _metadata;
679
+ _secondQueued[0].splitGroups = _splitGroup;
680
+ _secondQueued[0].fundAccessLimitGroups = _fundAccessLimitGroup;
681
+
682
+ // Queue the ruleset.
683
+ // Will follow the cycled over (ruleset #1) ruleset, after overriding the above config, because the first
684
+ // ruleset queued is in `ApprovalExpected` status (the 3 day deadline has not passed).
685
+ // Ruleset #1 rolls over because our `mustStartAtOrAfter` occurs later than when ruleset #1 ends.
686
+ vm.prank(multisig());
687
+ _controller.queueRulesetsOf(projectId, _secondQueued, "");
688
+
689
+ // Make sure this latest queued ruleset implies a cycled over ruleset from ruleset #1.
690
+ JBRuleset memory _requeued = jbRulesets().upcomingOf(projectId);
691
+ assertEq(_requeued.cycleNumber, 2);
692
+ assertEq(_requeued.id, _initialRulesetId);
693
+ assertEq(_requeued.weight, _weightInitial);
694
+
695
+ // Get a list of queued rulesets
696
+ JBRuleset[] memory queuedRulesets2 = jbRulesets().allOf(projectId, 0, 1);
697
+
698
+ // Ensure rulesetsOf is accurate
699
+ assertEq(queuedRulesets2[0].weight, _weightSecondQueued);
700
+
701
+ // Warp to when the initial ruleset rolls over and again becomes the current.
702
+ vm.warp(block.timestamp + _RULESET_DURATION);
703
+
704
+ // Make sure the new current is a rolled over ruleset.
705
+ JBRuleset memory _initialIsCurrent = jbRulesets().currentOf(projectId);
706
+ assertEq(_initialIsCurrent.cycleNumber, 2);
707
+ assertEq(_initialIsCurrent.id, _initialRulesetId);
708
+ assertEq(_initialIsCurrent.weight, _weightInitial);
709
+
710
+ // Second queued ruleset that replaced our first queued ruleset.
711
+ JBRuleset memory _requeued2 = jbRulesets().upcomingOf(projectId);
712
+ assertEq(_requeued2.cycleNumber, 3);
713
+ assertEq(_requeued2.id, _initialRulesetId + 2);
714
+ assertEq(_requeued2.weight, _weightSecondQueued);
715
+
716
+ // Get queued rulesets
717
+ JBRuleset[] memory queuedRulesets3 = jbRulesets().allOf(projectId, 0, 1);
718
+
719
+ // Ensure rulesetsOf is accurate
720
+ assertEq(queuedRulesets3[0].weight, _weightSecondQueued);
721
+ }
722
+
723
+ function testSingleBlockOverwriteQueued() public {
724
+ // Keep references to our different weights for assertions.
725
+ uint112 _weightFirstQueued = uint112(1234 * 10 ** 18);
726
+ uint112 _weightSecondQueued = uint112(6969 * 10 ** 18);
727
+
728
+ // Keep a reference to the expected ruleset ID (timestamp) after queuing, starting now, incremented later
729
+ // in-line for readability.
730
+ uint256 _expectedRulesetId = block.timestamp;
731
+
732
+ // Package up a config.
733
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](1);
734
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
735
+ _rulesetConfig[0].duration = 0;
736
+ _rulesetConfig[0].weight = _weight;
737
+ _rulesetConfig[0].weightCutPercent = 0;
738
+ _rulesetConfig[0].approvalHook = IJBRulesetApprovalHook(address(0));
739
+ _rulesetConfig[0].metadata = _metadata;
740
+ _rulesetConfig[0].splitGroups = _splitGroup;
741
+ _rulesetConfig[0].fundAccessLimitGroups = _fundAccessLimitGroup;
742
+
743
+ // Deploy a project to test.
744
+ uint256 projectId = launchProjectForTest();
745
+
746
+ // Keep a reference to the current ruleset.
747
+ JBRuleset memory _ruleset = jbRulesets().currentOf(projectId);
748
+
749
+ // Initial ruleset data: will have a `block.timestamp` (`rulesetId`) that is 2 less than the second queued
750
+ // ruleset (`rulesetId` timestamps are incremented when queued in same block).
751
+ assertEq(_ruleset.cycleNumber, 1);
752
+ assertEq(_ruleset.weight, _weight);
753
+
754
+ // Package up another config.
755
+ JBRulesetConfig[] memory _firstQueued = new JBRulesetConfig[](1);
756
+ _firstQueued[0].mustStartAtOrAfter = uint48(block.timestamp + 3 days);
757
+ _firstQueued[0].duration = _RULESET_DURATION;
758
+ _firstQueued[0].weight = _weightFirstQueued;
759
+ _firstQueued[0].weightCutPercent = 0;
760
+ _firstQueued[0].approvalHook = _deadline; // 3 day deadline duration.
761
+ _firstQueued[0].metadata = _metadata;
762
+ _firstQueued[0].splitGroups = _splitGroup;
763
+ _firstQueued[0].fundAccessLimitGroups = _fundAccessLimitGroup;
764
+
765
+ // Becomes queued & will be overwritten as 3 days will not pass and its status is `ApprovalExpected`.
766
+ vm.prank(multisig());
767
+ _controller.queueRulesetsOf(projectId, _firstQueued, "");
768
+
769
+ // Get a reference to the queued cycle.
770
+ JBRuleset memory queuedToOverwrite = jbRulesets().upcomingOf(projectId);
771
+
772
+ assertEq(queuedToOverwrite.cycleNumber, 2);
773
+ assertEq(queuedToOverwrite.id, _expectedRulesetId + 1);
774
+ assertEq(queuedToOverwrite.weight, _weightFirstQueued);
775
+
776
+ // Package up another config to overwrite.
777
+ JBRulesetConfig[] memory _secondQueued = new JBRulesetConfig[](1);
778
+
779
+ _secondQueued[0].mustStartAtOrAfter = uint48(block.timestamp + _DEADLINE_DURATION);
780
+ _secondQueued[0].duration = _RULESET_DURATION;
781
+ _secondQueued[0].weight = _weightSecondQueued;
782
+ _secondQueued[0].weightCutPercent = 0;
783
+ _secondQueued[0].approvalHook = _deadline; // 3 day deadline duration.
784
+ _secondQueued[0].metadata = _metadata;
785
+ _secondQueued[0].splitGroups = _splitGroup;
786
+ _secondQueued[0].fundAccessLimitGroups = _fundAccessLimitGroup;
787
+
788
+ // Queuing the second ruleset will overwrite the first queued ruleset.
789
+ vm.prank(multisig());
790
+ _controller.queueRulesetsOf(projectId, _secondQueued, "");
791
+
792
+ // Make sure it's overwritten.
793
+ JBRuleset memory queued = jbRulesets().upcomingOf(projectId);
794
+ assertEq(queued.cycleNumber, 2);
795
+ assertEq(queued.id, _expectedRulesetId + 2);
796
+ assertEq(queued.weight, _weightSecondQueued);
797
+ }
798
+
799
+ function testApprovalHook(uint256 _start, uint256 _rulesetId, uint256 _duration) public {
800
+ _start = bound(_start, block.timestamp, block.timestamp + 1000 days);
801
+ _rulesetId = bound(_rulesetId, block.timestamp, block.timestamp + 1000 days);
802
+ _duration = bound(_duration, 1, block.timestamp);
803
+
804
+ JBRuleset memory _ruleset = JBRuleset({
805
+ id: uint48(_rulesetId),
806
+ basedOnId: 0,
807
+ cycleNumber: 1,
808
+ start: uint48(_start),
809
+ duration: uint32(_duration),
810
+ weight: 1,
811
+ weightCutPercent: 0,
812
+ metadata: 0,
813
+ approvalHook: IJBRulesetApprovalHook(address(0))
814
+ });
815
+
816
+ JBDeadline deadline = new JBDeadline(_duration);
817
+
818
+ JBApprovalStatus _currentStatus = deadline.approvalStatusOf(1, _ruleset); // 1 is the `projectId`,
819
+ // unused
820
+
821
+ // Ruleset ID (timestamp) is after deadline -> approval hook failed.
822
+ if (_rulesetId > _start) {
823
+ assertEq(uint256(_currentStatus), uint256(JBApprovalStatus.Failed));
824
+ }
825
+ // Deadline starts less than a `duration` away from the `rulesetId` -> failed (would start mid-ruleset).
826
+ else if (_start - _duration < _rulesetId) {
827
+ assertEq(uint256(_currentStatus), uint256(JBApprovalStatus.Failed));
828
+ }
829
+ // Deadline starts more than a `_duration` away (will be approved when enough time has passed) -> approval
830
+ // expected.
831
+ else if (block.timestamp + _duration < _start) {
832
+ assertEq(uint256(_currentStatus), uint256(JBApprovalStatus.ApprovalExpected));
833
+ }
834
+ // If enough time has passed since deadline start, approved.
835
+ else if (block.timestamp + _duration > _start) {
836
+ assertEq(uint256(_currentStatus), uint256(JBApprovalStatus.Approved));
837
+ }
838
+ }
839
+
840
+ function testRulesetViewAccuracy() public {
841
+ // setup: deploy project and queue 2 rulesets atop the initial ruleset
842
+ uint256 id = launchProjectForTestWithThreeRulesets();
843
+
844
+ // Get a list of queued rulesets
845
+ JBRuleset[] memory rulesetsOf = jbRulesets().allOf(id, 0, 3);
846
+
847
+ // check: three rulesets returned
848
+ assertEq(rulesetsOf.length, 3);
849
+
850
+ // check: queued with furthest start time
851
+ assertEq(rulesetsOf[0].weight, _weight + 200);
852
+
853
+ // check: queued with nearest start time
854
+ assertEq(rulesetsOf[1].weight, _weight + 100);
855
+
856
+ // check: current with nearest start time
857
+ assertEq(rulesetsOf[2].weight, _weight);
858
+
859
+ // get the current ruleset
860
+ JBRuleset memory currentRuleset = jbRulesets().currentOf(id);
861
+
862
+ // check: current should be the initial ruleset
863
+ assertEq(currentRuleset.weight, _weight);
864
+
865
+ // get upcoming ruleset
866
+ JBRuleset memory upcomingRuleset = jbRulesets().upcomingOf(id);
867
+
868
+ // check: upcoming ruleset should be 2nd queued
869
+ assertEq(upcomingRuleset.weight, _weight + 100);
870
+
871
+ // Get a list of queued rulesets
872
+ rulesetsOf = jbRulesets().allOf(id, 0, 3);
873
+
874
+ // check: three rulesets returned again
875
+ assertEq(rulesetsOf.length, 3);
876
+
877
+ // check: queued with furthest start time
878
+ assertEq(rulesetsOf[0].weight, _weight + 200);
879
+
880
+ // check: current with nearest start time
881
+ assertEq(rulesetsOf[1].weight, _weight + 100);
882
+
883
+ // check: past with nearest start time
884
+ assertEq(rulesetsOf[2].weight, _weight);
885
+
886
+ // Get a list of queued rulesets
887
+ rulesetsOf = jbRulesets().allOf(id, 0, 2);
888
+
889
+ // check: two rulesets returned again
890
+ assertEq(rulesetsOf.length, 2);
891
+
892
+ // check: queued with furthest start time
893
+ assertEq(rulesetsOf[0].weight, _weight + 200);
894
+
895
+ // check: current with nearest start time
896
+ assertEq(rulesetsOf[1].weight, _weight + 100);
897
+
898
+ // Get a list of queued rulesets
899
+ rulesetsOf = jbRulesets().allOf(id, upcomingRuleset.id, 2);
900
+
901
+ // check: two rulesets returned again
902
+ assertEq(rulesetsOf.length, 2);
903
+
904
+ // check: current with nearest start time
905
+ assertEq(rulesetsOf[0].weight, _weight + 100);
906
+
907
+ // check: past with nearest start time
908
+ assertEq(rulesetsOf[1].weight, _weight);
909
+
910
+ // Get a list of queued rulesets
911
+ rulesetsOf = jbRulesets().allOf(id, upcomingRuleset.id, 1);
912
+
913
+ // check: one rulesets returned again
914
+ assertEq(rulesetsOf.length, 1);
915
+
916
+ // check: current with nearest start time
917
+ assertEq(rulesetsOf[0].weight, _weight + 100);
918
+
919
+ // Get a list of queued rulesets with a larger size than there are rulesets.
920
+ rulesetsOf = jbRulesets().allOf(id, 0, 10);
921
+
922
+ // check: three rulesets returned
923
+ assertEq(rulesetsOf.length, 3);
924
+
925
+ // check: queued with furthest start time
926
+ assertEq(rulesetsOf[0].weight, _weight + 200);
927
+
928
+ // check: queued with nearest start time
929
+ assertEq(rulesetsOf[1].weight, _weight + 100);
930
+
931
+ // check: current with nearest start time
932
+ assertEq(rulesetsOf[2].weight, _weight);
933
+ }
934
+
935
+ function testWithThreeHistoricalRulesets() public {
936
+ // Package up ruleset configuration.
937
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](3);
938
+
939
+ // first ruleset in the past
940
+ _rulesetConfig[0].mustStartAtOrAfter = uint48(block.timestamp - 2 days);
941
+ _rulesetConfig[0].duration = 1 hours;
942
+ _rulesetConfig[0].weight = uint112(_weight);
943
+ _rulesetConfig[0].weightCutPercent = 0;
944
+ _rulesetConfig[0].approvalHook = IJBRulesetApprovalHook(address(0));
945
+ _rulesetConfig[0].metadata = _metadata;
946
+ _rulesetConfig[0].splitGroups = new JBSplitGroup[](0);
947
+ _rulesetConfig[0].fundAccessLimitGroups = new JBFundAccessLimitGroup[](0);
948
+
949
+ // second ruleset started in the past but should still be active
950
+ _rulesetConfig[1].mustStartAtOrAfter = uint48(block.timestamp - 2 hours);
951
+ _rulesetConfig[1].duration = 1 hours;
952
+ _rulesetConfig[1].weight = uint112(_weight + 100);
953
+ _rulesetConfig[1].weightCutPercent = 0;
954
+ _rulesetConfig[1].approvalHook = IJBRulesetApprovalHook(address(0));
955
+ _rulesetConfig[1].metadata = _metadata;
956
+ _rulesetConfig[1].splitGroups = new JBSplitGroup[](0);
957
+ _rulesetConfig[1].fundAccessLimitGroups = new JBFundAccessLimitGroup[](0);
958
+
959
+ // third
960
+ _rulesetConfig[2].mustStartAtOrAfter = uint48(block.timestamp + 1 days);
961
+ _rulesetConfig[2].duration = 1 days;
962
+ _rulesetConfig[2].weight = uint112(_weight + 200);
963
+ _rulesetConfig[2].weightCutPercent = 0;
964
+ _rulesetConfig[2].approvalHook = IJBRulesetApprovalHook(address(0));
965
+ _rulesetConfig[2].metadata = _metadata;
966
+ _rulesetConfig[2].splitGroups = new JBSplitGroup[](0);
967
+ _rulesetConfig[2].fundAccessLimitGroups = new JBFundAccessLimitGroup[](0);
968
+
969
+ // Package up terminal configuration.
970
+ JBTerminalConfig[] memory _terminalConfigurations = new JBTerminalConfig[](1);
971
+ JBAccountingContext[] memory _tokensToAccept = new JBAccountingContext[](1);
972
+ _tokensToAccept[0] = JBAccountingContext({
973
+ token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
974
+ });
975
+ _terminalConfigurations[0] =
976
+ JBTerminalConfig({terminal: _terminal, accountingContextsToAccept: _tokensToAccept});
977
+
978
+ uint256 projectId = _controller.launchProjectFor({
979
+ owner: address(multisig()),
980
+ projectUri: "myIPFSHash",
981
+ rulesetConfigurations: _rulesetConfig,
982
+ terminalConfigurations: _terminalConfigurations,
983
+ memo: ""
984
+ });
985
+
986
+ // Get a list of queued rulesets
987
+ JBRuleset[] memory rulesetsOf = jbRulesets().allOf(projectId, 0, 3);
988
+
989
+ // check: three rulesets returned
990
+ assertEq(rulesetsOf.length, 3);
991
+
992
+ // get the current ruleset
993
+ JBRuleset memory currentRuleset = jbRulesets().currentOf(projectId);
994
+
995
+ // check: current should be the second ruleset
996
+ assertEq(currentRuleset.weight, _weight + 100);
997
+
998
+ // check: current should be an iterated cycle.
999
+ assertEq(currentRuleset.cycleNumber, (2 days / 1 hours) + 1);
1000
+ }
1001
+ }