@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,286 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.6;
3
+
4
+ import /* {*} from */ "./helpers/TestBaseWorkflow.sol";
5
+
6
+ /// @notice Defense-in-depth validation of JBPermissions ROOT escalation prevention.
7
+ /// Verifies that ROOT operators cannot forward ROOT, cannot set wildcard permissions,
8
+ /// and that the permission bitmap maintains integrity through set/get cycles.
9
+ contract TestPermissionsEdge_Local is TestBaseWorkflow {
10
+ JBPermissions private _permissions;
11
+
12
+ address private _account;
13
+ address private _operator;
14
+ address private _thirdParty;
15
+
16
+ uint64 constant PROJECT_ID = 5;
17
+
18
+ function setUp() public override {
19
+ super.setUp();
20
+ _permissions = jbPermissions();
21
+ _account = makeAddr("account");
22
+ _operator = makeAddr("operator");
23
+ _thirdParty = makeAddr("thirdParty");
24
+ }
25
+
26
+ // ───────────────────── ROOT cannot be forwarded
27
+ // ─────────────────────
28
+
29
+ /// @notice An operator with ROOT on project N cannot set ROOT for another operator.
30
+ function test_rootCannotBeForwarded() external {
31
+ // Give operator ROOT permission on PROJECT_ID.
32
+ uint8[] memory rootPermissions = new uint8[](1);
33
+ rootPermissions[0] = JBPermissionIds.ROOT;
34
+
35
+ vm.prank(_account);
36
+ _permissions.setPermissionsFor(
37
+ _account, JBPermissionsData({operator: _operator, projectId: PROJECT_ID, permissionIds: rootPermissions})
38
+ );
39
+
40
+ // Verify operator has ROOT.
41
+ assertTrue(
42
+ _permissions.hasPermission(_operator, _account, PROJECT_ID, JBPermissionIds.ROOT, false, false),
43
+ "Operator should have ROOT"
44
+ );
45
+
46
+ // Now operator tries to forward ROOT to thirdParty.
47
+ uint8[] memory rootForThird = new uint8[](1);
48
+ rootForThird[0] = JBPermissionIds.ROOT;
49
+
50
+ vm.prank(_operator);
51
+ vm.expectRevert(
52
+ abi.encodeWithSelector(
53
+ JBPermissions.JBPermissions_Unauthorized.selector, _account, _operator, PROJECT_ID, JBPermissionIds.ROOT
54
+ )
55
+ );
56
+ _permissions.setPermissionsFor(
57
+ _account, JBPermissionsData({operator: _thirdParty, projectId: PROJECT_ID, permissionIds: rootForThird})
58
+ );
59
+ }
60
+
61
+ // ───────────────────── Wildcard cannot be set by operator
62
+ // ─────────────────────
63
+
64
+ /// @notice An operator with ROOT cannot set permissions for the wildcard project ID.
65
+ function test_wildcardCannotBeSetByOperator() external {
66
+ // Give operator ROOT on PROJECT_ID.
67
+ uint8[] memory rootPermissions = new uint8[](1);
68
+ rootPermissions[0] = JBPermissionIds.ROOT;
69
+
70
+ vm.prank(_account);
71
+ _permissions.setPermissionsFor(
72
+ _account, JBPermissionsData({operator: _operator, projectId: PROJECT_ID, permissionIds: rootPermissions})
73
+ );
74
+
75
+ // Operator tries to set permissions on wildcard (project 0).
76
+ uint8[] memory somePermission = new uint8[](1);
77
+ somePermission[0] = 5; // Some non-ROOT permission.
78
+
79
+ vm.prank(_operator);
80
+ vm.expectRevert(
81
+ abi.encodeWithSelector(
82
+ JBPermissions.JBPermissions_Unauthorized.selector, _account, _operator, 0, JBPermissionIds.ROOT
83
+ )
84
+ );
85
+ _permissions.setPermissionsFor(
86
+ _account, JBPermissionsData({operator: _thirdParty, projectId: 0, permissionIds: somePermission})
87
+ );
88
+ }
89
+
90
+ // ───────────────────── ROOT grants all permissions
91
+ // ─────────────────────
92
+
93
+ /// @notice Fuzz: ROOT holder always has permission for any ID (when includeRoot=true).
94
+ function testFuzz_rootGrantsAllPermissions(uint8 permissionId) external {
95
+ vm.assume(permissionId > 0); // 0 is reserved.
96
+
97
+ // Give operator ROOT.
98
+ uint8[] memory rootPermissions = new uint8[](1);
99
+ rootPermissions[0] = JBPermissionIds.ROOT;
100
+
101
+ vm.prank(_account);
102
+ _permissions.setPermissionsFor(
103
+ _account, JBPermissionsData({operator: _operator, projectId: PROJECT_ID, permissionIds: rootPermissions})
104
+ );
105
+
106
+ // Check any permissionId with includeRoot=true.
107
+ assertTrue(
108
+ _permissions.hasPermission(_operator, _account, PROJECT_ID, permissionId, true, false),
109
+ "ROOT should grant all permissions when includeRoot=true"
110
+ );
111
+
112
+ // Without includeRoot, only ROOT bit should be set.
113
+ if (permissionId != JBPermissionIds.ROOT) {
114
+ assertFalse(
115
+ _permissions.hasPermission(_operator, _account, PROJECT_ID, permissionId, false, false),
116
+ "Without includeRoot, only ROOT bit should match"
117
+ );
118
+ }
119
+ }
120
+
121
+ // ───────────────────── Permission ID boundaries
122
+ // ─────────────────────
123
+
124
+ /// @notice Permission 0 cannot be set.
125
+ function test_permissionId0_cannotBeSet() external {
126
+ uint8[] memory zeroPermission = new uint8[](1);
127
+ zeroPermission[0] = 0;
128
+
129
+ vm.prank(_account);
130
+ vm.expectRevert(JBPermissions.JBPermissions_NoZeroPermission.selector);
131
+ _permissions.setPermissionsFor(
132
+ _account, JBPermissionsData({operator: _operator, projectId: PROJECT_ID, permissionIds: zeroPermission})
133
+ );
134
+ }
135
+
136
+ /// @notice Permission 255 (highest) works correctly.
137
+ function test_permissionId255_works() external {
138
+ uint8[] memory maxPermission = new uint8[](1);
139
+ maxPermission[0] = 255;
140
+
141
+ vm.prank(_account);
142
+ _permissions.setPermissionsFor(
143
+ _account, JBPermissionsData({operator: _operator, projectId: PROJECT_ID, permissionIds: maxPermission})
144
+ );
145
+
146
+ assertTrue(
147
+ _permissions.hasPermission(_operator, _account, PROJECT_ID, 255, false, false), "Permission 255 should work"
148
+ );
149
+
150
+ // Permission 254 should NOT be set.
151
+ assertFalse(
152
+ _permissions.hasPermission(_operator, _account, PROJECT_ID, 254, false, false),
153
+ "Permission 254 should not be set"
154
+ );
155
+ }
156
+
157
+ // ───────────────────── Replacement not additive
158
+ // ─────────────────────
159
+
160
+ /// @notice Setting new permissions replaces old ones (old permissions lost).
161
+ function test_replacementNotAdditive() external {
162
+ // Set permission 5.
163
+ uint8[] memory perm5 = new uint8[](1);
164
+ perm5[0] = 5;
165
+
166
+ vm.prank(_account);
167
+ _permissions.setPermissionsFor(
168
+ _account, JBPermissionsData({operator: _operator, projectId: PROJECT_ID, permissionIds: perm5})
169
+ );
170
+
171
+ assertTrue(_permissions.hasPermission(_operator, _account, PROJECT_ID, 5, false, false), "Should have perm 5");
172
+
173
+ // Now set permission 10 — should REPLACE, not add to perm 5.
174
+ uint8[] memory perm10 = new uint8[](1);
175
+ perm10[0] = 10;
176
+
177
+ vm.prank(_account);
178
+ _permissions.setPermissionsFor(
179
+ _account, JBPermissionsData({operator: _operator, projectId: PROJECT_ID, permissionIds: perm10})
180
+ );
181
+
182
+ assertTrue(_permissions.hasPermission(_operator, _account, PROJECT_ID, 10, false, false), "Should have perm 10");
183
+ assertFalse(
184
+ _permissions.hasPermission(_operator, _account, PROJECT_ID, 5, false, false),
185
+ "Perm 5 should be LOST after replacement"
186
+ );
187
+ }
188
+
189
+ // ───────────────────── Wildcard overrides project-specific
190
+ // ─────────────────────
191
+
192
+ /// @notice Wildcard permission grants access to all projects.
193
+ function test_wildcardOverridesProjectSpecific() external {
194
+ // Set permission 5 on wildcard project (0).
195
+ uint8[] memory perm5 = new uint8[](1);
196
+ perm5[0] = 5;
197
+
198
+ vm.prank(_account);
199
+ _permissions.setPermissionsFor(
200
+ _account, JBPermissionsData({operator: _operator, projectId: 0, permissionIds: perm5})
201
+ );
202
+
203
+ // Check with includeWildcardProjectId=true on any project.
204
+ assertTrue(
205
+ _permissions.hasPermission(_operator, _account, PROJECT_ID, 5, false, true),
206
+ "Wildcard should grant permission on any project"
207
+ );
208
+
209
+ // Check without wildcard — should not have permission on specific project.
210
+ assertFalse(
211
+ _permissions.hasPermission(_operator, _account, PROJECT_ID, 5, false, false),
212
+ "Without wildcard flag, specific project check fails"
213
+ );
214
+ }
215
+
216
+ // ───────────────────── Bit integrity fuzz
217
+ // ─────────────────────
218
+
219
+ /// @notice Fuzz: packed permissions maintain bit integrity through set/get cycle.
220
+ function testFuzz_setPermissions_bitIntegrity(uint256 bitmap) external {
221
+ // Build permission ID array from bitmap.
222
+ // Count set bits (excluding bit 0).
223
+ uint256 count;
224
+ for (uint256 i = 1; i < 256; i++) {
225
+ if ((bitmap >> i) & 1 == 1) count++;
226
+ }
227
+
228
+ if (count == 0) return; // Skip empty bitmaps.
229
+
230
+ uint8[] memory ids = new uint8[](count);
231
+ uint256 idx;
232
+ for (uint256 i = 1; i < 256; i++) {
233
+ if ((bitmap >> i) & 1 == 1) {
234
+ ids[idx] = uint8(i);
235
+ idx++;
236
+ }
237
+ }
238
+
239
+ vm.prank(_account);
240
+ _permissions.setPermissionsFor(
241
+ _account, JBPermissionsData({operator: _operator, projectId: PROJECT_ID, permissionIds: ids})
242
+ );
243
+
244
+ // Verify packed value matches.
245
+ uint256 packed = _permissions.permissionsOf(_operator, _account, PROJECT_ID);
246
+
247
+ // Check each bit.
248
+ for (uint256 i = 1; i < 256; i++) {
249
+ bool expected = (bitmap >> i) & 1 == 1;
250
+ bool actual = ((packed >> i) & 1) == 1;
251
+ assertEq(actual, expected, string.concat("Bit mismatch at position ", vm.toString(i)));
252
+ }
253
+
254
+ // Bit 0 should never be set.
255
+ assertFalse(((packed >> 0) & 1) == 1, "Bit 0 should never be set");
256
+ }
257
+
258
+ // ───────────────────── ROOT operator can set non-ROOT permissions
259
+ // ─────────────────────
260
+
261
+ /// @notice ROOT operator CAN set non-ROOT permissions for others on the same project.
262
+ function test_rootOperator_canSetNonRootPermissions() external {
263
+ // Give operator ROOT.
264
+ uint8[] memory rootPermissions = new uint8[](1);
265
+ rootPermissions[0] = JBPermissionIds.ROOT;
266
+
267
+ vm.prank(_account);
268
+ _permissions.setPermissionsFor(
269
+ _account, JBPermissionsData({operator: _operator, projectId: PROJECT_ID, permissionIds: rootPermissions})
270
+ );
271
+
272
+ // Operator sets non-ROOT permission for thirdParty — should succeed.
273
+ uint8[] memory nonRootPerm = new uint8[](1);
274
+ nonRootPerm[0] = 5;
275
+
276
+ vm.prank(_operator);
277
+ _permissions.setPermissionsFor(
278
+ _account, JBPermissionsData({operator: _thirdParty, projectId: PROJECT_ID, permissionIds: nonRootPerm})
279
+ );
280
+
281
+ assertTrue(
282
+ _permissions.hasPermission(_thirdParty, _account, PROJECT_ID, 5, false, false),
283
+ "ROOT operator should be able to delegate non-ROOT permissions"
284
+ );
285
+ }
286
+ }
@@ -0,0 +1,339 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity >=0.8.6;
3
+
4
+ import /* {*} from */ "./helpers/TestBaseWorkflow.sol";
5
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
6
+ import {MockPriceFeed} from "./mock/MockPriceFeed.sol";
7
+
8
+ contract TestPermit2Terminal_Local is TestBaseWorkflow {
9
+ uint112 private constant _WEIGHT = uint112(1000 * 10 ** 18);
10
+
11
+ IJBController private _controller;
12
+ IJBTerminal private _terminal;
13
+ IJBPrices private _prices;
14
+ IJBTokens private _tokens;
15
+ IERC20 private _usdc;
16
+ IPermit2 private _permit2;
17
+ MetadataResolverHelper private _helper;
18
+ address private _projectOwner;
19
+
20
+ uint256 _projectId;
21
+
22
+ // Permit2 params.
23
+ bytes32 DOMAIN_SEPARATOR;
24
+ address from;
25
+ uint256 fromPrivateKey;
26
+
27
+ // Price.
28
+ uint256 _nativePricePerUsd = 0.0005 * 10 ** 18; // 1/2000
29
+
30
+ function setUp() public override {
31
+ super.setUp();
32
+
33
+ _controller = jbController();
34
+ _projectOwner = multisig();
35
+ _terminal = jbMultiTerminal();
36
+ _prices = jbPrices();
37
+ _tokens = jbTokens();
38
+ _helper = metadataHelper();
39
+ _usdc = usdcToken();
40
+ _permit2 = permit2();
41
+
42
+ fromPrivateKey = 0x12341234;
43
+ from = vm.addr(fromPrivateKey);
44
+ DOMAIN_SEPARATOR = permit2().DOMAIN_SEPARATOR();
45
+
46
+ JBRulesetMetadata memory _metadata = JBRulesetMetadata({
47
+ reservedPercent: 0,
48
+ cashOutTaxRate: JBConstants.MAX_CASH_OUT_TAX_RATE,
49
+ baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
50
+ pausePay: false,
51
+ pauseCreditTransfers: false,
52
+ allowOwnerMinting: true,
53
+ allowSetCustomToken: true,
54
+ allowTerminalMigration: false,
55
+ allowSetTerminals: false,
56
+ ownerMustSendPayouts: false,
57
+ allowSetController: false,
58
+ allowAddAccountingContext: true,
59
+ allowAddPriceFeed: true,
60
+ holdFees: false,
61
+ useTotalSurplusForCashOuts: false,
62
+ useDataHookForPay: false,
63
+ useDataHookForCashOut: false,
64
+ dataHook: address(0),
65
+ metadata: 0
66
+ });
67
+
68
+ // Package up ruleset configuration.
69
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](1);
70
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
71
+ _rulesetConfig[0].duration = 0;
72
+ _rulesetConfig[0].weight = _WEIGHT;
73
+ _rulesetConfig[0].weightCutPercent = 0;
74
+ _rulesetConfig[0].approvalHook = IJBRulesetApprovalHook(address(0));
75
+ _rulesetConfig[0].metadata = _metadata;
76
+ _rulesetConfig[0].splitGroups = new JBSplitGroup[](0);
77
+ _rulesetConfig[0].fundAccessLimitGroups = new JBFundAccessLimitGroup[](0);
78
+
79
+ JBTerminalConfig[] memory _terminalConfigurations = new JBTerminalConfig[](1);
80
+ JBAccountingContext[] memory _tokensToAccept = new JBAccountingContext[](2);
81
+ _tokensToAccept[0] = JBAccountingContext({
82
+ token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
83
+ });
84
+ _tokensToAccept[1] = JBAccountingContext({
85
+ token: address(usdcToken()), decimals: 6, currency: uint32(uint160(address(usdcToken())))
86
+ });
87
+ _terminalConfigurations[0] =
88
+ JBTerminalConfig({terminal: _terminal, accountingContextsToAccept: _tokensToAccept});
89
+
90
+ // Create a first project to collect fees.
91
+ _controller.launchProjectFor({
92
+ owner: _projectOwner,
93
+ projectUri: "myIPFSHash",
94
+ rulesetConfigurations: _rulesetConfig,
95
+ terminalConfigurations: _terminalConfigurations,
96
+ memo: ""
97
+ });
98
+
99
+ _projectId = _controller.launchProjectFor({
100
+ owner: _projectOwner,
101
+ projectUri: "myIPFSHash",
102
+ rulesetConfigurations: _rulesetConfig,
103
+ terminalConfigurations: _terminalConfigurations,
104
+ memo: ""
105
+ });
106
+
107
+ vm.startPrank(_projectOwner);
108
+ MockPriceFeed _priceFeedNativeUsd = new MockPriceFeed(_nativePricePerUsd, 18);
109
+ vm.label(address(_priceFeedNativeUsd), "Mock Price Feed Native-USD");
110
+
111
+ _controller.addPriceFeed({
112
+ projectId: _projectId,
113
+ pricingCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
114
+ unitCurrency: uint32(uint160(address(usdcToken()))),
115
+ feed: _priceFeedNativeUsd
116
+ });
117
+
118
+ vm.stopPrank();
119
+ }
120
+
121
+ function testFuzzPayPermit2(uint256 _coins, uint256 _expiration, uint256 _deadline) public {
122
+ // Setup: set fuzz boundaries.
123
+ _coins = bound(_coins, 0, uint256(type(uint160).max) + 1);
124
+ _expiration = bound(_expiration, block.timestamp + 1, type(uint48).max - 1);
125
+ _deadline = bound(_deadline, block.timestamp + 1, type(uint256).max - 1);
126
+
127
+ // Setup: prepare permit details for signing.
128
+ IAllowanceTransfer.PermitDetails memory details = IAllowanceTransfer.PermitDetails({
129
+ token: address(_usdc), amount: uint160(_coins), expiration: uint48(_expiration), nonce: 0
130
+ });
131
+
132
+ IAllowanceTransfer.PermitSingle memory permit =
133
+ IAllowanceTransfer.PermitSingle({details: details, spender: address(_terminal), sigDeadline: _deadline});
134
+
135
+ // Setup: sign permit details.
136
+ bytes memory sig = getPermitSignature(permit, fromPrivateKey, DOMAIN_SEPARATOR);
137
+
138
+ JBSingleAllowance memory permitData = JBSingleAllowance({
139
+ sigDeadline: _deadline,
140
+ amount: uint160(_coins),
141
+ expiration: uint48(_expiration),
142
+ nonce: uint48(0),
143
+ signature: sig
144
+ });
145
+
146
+ // Setup: prepare data for metadata helper.
147
+ bytes4[] memory _ids = new bytes4[](1);
148
+ bytes[] memory _datas = new bytes[](1);
149
+ _datas[0] = abi.encode(permitData);
150
+ _ids[0] = _helper.getId("permit2", address(_terminal));
151
+
152
+ // Setup: use the metadata library to encode.
153
+ bytes memory _packedData = _helper.createMetadata(_ids, _datas);
154
+
155
+ // Setup: give coins and approve permit2 contract.
156
+ deal(address(_usdc), from, _coins);
157
+ vm.prank(from);
158
+ IERC20(address(_usdc)).approve(address(permit2()), _coins);
159
+
160
+ if (_coins == uint256(type(uint160).max) + 1) {
161
+ vm.expectRevert(
162
+ abi.encodeWithSelector(JBMultiTerminal.JBMultiTerminal_PermitAllowanceNotEnough.selector, _coins, 0)
163
+ );
164
+ }
165
+
166
+ vm.prank(from);
167
+ uint256 _minted = _terminal.pay({
168
+ projectId: _projectId,
169
+ amount: _coins,
170
+ token: address(_usdc),
171
+ beneficiary: from,
172
+ minReturnedTokens: 0,
173
+ memo: "Take my permitted money!",
174
+ metadata: _packedData
175
+ });
176
+
177
+ if (_coins < uint256(type(uint160).max) + 1) {
178
+ // Check: that tokens were transfered.
179
+ assertEq(_usdc.balanceOf(address(_terminal)), _coins);
180
+
181
+ // Check: that payer receives project token/balance.
182
+ assertEq(_tokens.totalBalanceOf(from, _projectId), _minted);
183
+ }
184
+ }
185
+
186
+ function testFuzzAddToBalancePermit2(uint256 _coins, uint256 _expiration, uint256 _deadline) public {
187
+ // Setup: set fuzz boundaries.
188
+ _coins = bound(_coins, 0, uint256(type(uint160).max) + 1);
189
+ _expiration = bound(_expiration, block.timestamp + 1, type(uint48).max - 1);
190
+ _deadline = bound(_deadline, block.timestamp + 1, type(uint256).max - 1);
191
+
192
+ // Setup: prepare permit details for signing.
193
+ IAllowanceTransfer.PermitDetails memory details = IAllowanceTransfer.PermitDetails({
194
+ token: address(_usdc), amount: uint160(_coins), expiration: uint48(_expiration), nonce: 0
195
+ });
196
+
197
+ IAllowanceTransfer.PermitSingle memory permit =
198
+ IAllowanceTransfer.PermitSingle({details: details, spender: address(_terminal), sigDeadline: _deadline});
199
+
200
+ // Setup: sign permit details.
201
+ bytes memory sig = getPermitSignature(permit, fromPrivateKey, DOMAIN_SEPARATOR);
202
+
203
+ JBSingleAllowance memory permitData = JBSingleAllowance({
204
+ sigDeadline: _deadline,
205
+ amount: uint160(_coins),
206
+ expiration: uint48(_expiration),
207
+ nonce: uint48(0),
208
+ signature: sig
209
+ });
210
+
211
+ // Setup: prepare data for metadata helper.
212
+ bytes4[] memory _ids = new bytes4[](1);
213
+ bytes[] memory _datas = new bytes[](1);
214
+ _datas[0] = abi.encode(permitData);
215
+ _ids[0] = _helper.getId("permit2", address(_terminal));
216
+
217
+ // Setup: use the metadata library to encode.
218
+ bytes memory _packedData = _helper.createMetadata(_ids, _datas);
219
+
220
+ // Setup: give coins and approve permit2 contract.
221
+ deal(address(_usdc), from, _coins);
222
+ vm.prank(from);
223
+ IERC20(address(_usdc)).approve(address(permit2()), _coins);
224
+
225
+ if (_coins == uint256(type(uint160).max) + 1) {
226
+ vm.expectRevert(
227
+ abi.encodeWithSelector(JBMultiTerminal.JBMultiTerminal_PermitAllowanceNotEnough.selector, _coins, 0)
228
+ );
229
+ }
230
+
231
+ // Test: add to balance using permit2 data, which should transfer tokens.
232
+ vm.prank(from);
233
+ _terminal.addToBalanceOf(_projectId, address(_usdc), _coins, false, "testing permit2", _packedData);
234
+
235
+ // Check: that tokens were transferred.
236
+ if (_coins < uint256(type(uint160).max) + 1) assertEq(_usdc.balanceOf(address(_terminal)), _coins);
237
+ }
238
+
239
+ function testPayAmountGtMaxPermit() public {
240
+ // Setup: refs
241
+ uint160 _permitAmount = type(uint160).max;
242
+ uint256 _payAmount = type(uint256).max;
243
+ uint256 _sigDeadline = block.timestamp + 1;
244
+ uint48 _expiration = type(uint48).max;
245
+ uint48 _nonce = 0;
246
+
247
+ // Setup: prepare permit details for signing.
248
+ IAllowanceTransfer.PermitDetails memory details = IAllowanceTransfer.PermitDetails({
249
+ token: address(_usdc), amount: _permitAmount, expiration: _expiration, nonce: 0
250
+ });
251
+
252
+ IAllowanceTransfer.PermitSingle memory permit =
253
+ IAllowanceTransfer.PermitSingle({details: details, spender: address(_terminal), sigDeadline: _sigDeadline});
254
+
255
+ // Setup: sign permit details.
256
+ bytes memory sig = getPermitSignature(permit, fromPrivateKey, DOMAIN_SEPARATOR);
257
+
258
+ JBSingleAllowance({
259
+ sigDeadline: _sigDeadline, amount: _permitAmount, expiration: _expiration, nonce: _nonce, signature: sig
260
+ });
261
+
262
+ vm.expectRevert(
263
+ abi.encodeWithSelector(
264
+ JBMultiTerminal.JBMultiTerminal_OverflowAlert.selector, _payAmount, type(uint160).max
265
+ )
266
+ );
267
+
268
+ vm.prank(from);
269
+ _terminal.pay({
270
+ projectId: _projectId,
271
+ amount: _payAmount,
272
+ token: address(_usdc),
273
+ beneficiary: from,
274
+ minReturnedTokens: 0,
275
+ memo: "Take my permitted money!",
276
+ metadata: ""
277
+ });
278
+ }
279
+
280
+ /// Permit2 signature helpers.
281
+ /// (required because `permit2/test/utils/PermitSignature.sol` imports `draft-EIP712.sol` which is no longer a
282
+ /// draft.)
283
+
284
+ bytes32 public constant _PERMIT_DETAILS_TYPEHASH =
285
+ keccak256("PermitDetails(address token,uint160 amount,uint48 expiration,uint48 nonce)");
286
+
287
+ bytes32 public constant _PERMIT_SINGLE_TYPEHASH = keccak256(
288
+ "PermitSingle(PermitDetails details,address spender,uint256 sigDeadline)PermitDetails(address token,uint160 amount,uint48 expiration,uint48 nonce)"
289
+ );
290
+
291
+ bytes32 public constant _PERMIT_BATCH_TYPEHASH = keccak256(
292
+ "PermitBatch(PermitDetails[] details,address spender,uint256 sigDeadline)PermitDetails(address token,uint160 amount,uint48 expiration,uint48 nonce)"
293
+ );
294
+
295
+ bytes32 public constant _TOKEN_PERMISSIONS_TYPEHASH = keccak256("TokenPermissions(address token,uint256 amount)");
296
+
297
+ bytes32 public constant _PERMIT_TRANSFER_FROM_TYPEHASH = keccak256(
298
+ "PermitTransferFrom(TokenPermissions permitted,address spender,uint256 nonce,uint256 deadline)TokenPermissions(address token,uint256 amount)"
299
+ );
300
+
301
+ bytes32 public constant _PERMIT_BATCH_TRANSFER_FROM_TYPEHASH = keccak256(
302
+ "PermitBatchTransferFrom(TokenPermissions[] permitted,address spender,uint256 nonce,uint256 deadline)TokenPermissions(address token,uint256 amount)"
303
+ );
304
+
305
+ function getPermitSignatureRaw(
306
+ IAllowanceTransfer.PermitSingle memory permit,
307
+ uint256 privateKey,
308
+ bytes32 domainSeparator
309
+ )
310
+ internal
311
+ pure
312
+ returns (uint8 v, bytes32 r, bytes32 s)
313
+ {
314
+ bytes32 permitHash = keccak256(abi.encode(_PERMIT_DETAILS_TYPEHASH, permit.details));
315
+
316
+ bytes32 msgHash = keccak256(
317
+ abi.encodePacked(
318
+ "\x19\x01",
319
+ domainSeparator,
320
+ keccak256(abi.encode(_PERMIT_SINGLE_TYPEHASH, permitHash, permit.spender, permit.sigDeadline))
321
+ )
322
+ );
323
+
324
+ (v, r, s) = vm.sign(privateKey, msgHash);
325
+ }
326
+
327
+ function getPermitSignature(
328
+ IAllowanceTransfer.PermitSingle memory permit,
329
+ uint256 privateKey,
330
+ bytes32 domainSeparator
331
+ )
332
+ internal
333
+ pure
334
+ returns (bytes memory sig)
335
+ {
336
+ (uint8 v, bytes32 r, bytes32 s) = getPermitSignatureRaw(permit, privateKey, domainSeparator);
337
+ return bytes.concat(r, s, bytes1(v));
338
+ }
339
+ }