@bananapus/core-v6 0.0.37 → 0.0.39

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 (324) hide show
  1. package/foundry.lock +1 -7
  2. package/foundry.toml +1 -1
  3. package/package.json +19 -7
  4. package/src/JBChainlinkV3PriceFeed.sol +4 -1
  5. package/src/JBChainlinkV3SequencerPriceFeed.sol +4 -2
  6. package/src/JBController.sol +71 -44
  7. package/src/JBDeadline.sol +4 -4
  8. package/src/JBDirectory.sol +34 -32
  9. package/src/JBERC20.sol +5 -4
  10. package/src/JBFeelessAddresses.sol +6 -3
  11. package/src/JBFundAccessLimits.sol +25 -21
  12. package/src/JBMultiTerminal.sol +121 -84
  13. package/src/JBPermissions.sol +34 -37
  14. package/src/JBPrices.sol +23 -18
  15. package/src/JBProjects.sol +6 -3
  16. package/src/JBRulesets.sol +44 -41
  17. package/src/JBSplits.sol +18 -16
  18. package/src/JBTerminalStore.sol +32 -25
  19. package/src/JBTokens.sol +36 -26
  20. package/src/abstract/JBControlled.sol +3 -1
  21. package/src/abstract/JBPermissioned.sol +3 -1
  22. package/src/enums/JBApprovalStatus.sol +7 -1
  23. package/src/interfaces/IJBController.sol +7 -3
  24. package/src/interfaces/IJBDirectory.sol +3 -1
  25. package/src/interfaces/IJBMultiTerminal.sol +3 -2
  26. package/src/interfaces/IJBPermissions.sol +2 -1
  27. package/src/interfaces/IJBPrices.sol +3 -1
  28. package/src/interfaces/IJBRulesets.sol +2 -1
  29. package/src/interfaces/IJBSplits.sol +2 -1
  30. package/src/interfaces/IJBTerminal.sol +3 -1
  31. package/src/interfaces/IJBTerminalStore.sol +3 -1
  32. package/src/interfaces/IJBTokens.sol +2 -1
  33. package/src/libraries/JBCashOuts.sol +6 -1
  34. package/src/libraries/JBConstants.sol +12 -3
  35. package/src/libraries/JBCurrencyIds.sol +2 -0
  36. package/src/libraries/JBFees.sol +52 -10
  37. package/src/libraries/JBFixedPointNumber.sol +2 -0
  38. package/src/libraries/JBPayoutSplitGroupLib.sol +7 -4
  39. package/src/libraries/JBRulesetMetadataResolver.sol +4 -0
  40. package/src/libraries/JBSplitGroupIds.sol +2 -1
  41. package/src/libraries/JBSurplus.sol +3 -1
  42. package/src/periphery/JBMatchingPriceFeed.sol +3 -1
  43. package/src/structs/JBAccountingContext.sol +7 -4
  44. package/src/structs/JBFundAccessLimitGroup.sol +10 -17
  45. package/src/structs/JBRuleset.sol +18 -26
  46. package/src/structs/JBRulesetConfig.sol +13 -25
  47. package/src/structs/JBRulesetMetadata.sol +25 -32
  48. package/test/mock/MockMaliciousBeneficiary.sol +15 -15
  49. package/ADMINISTRATION.md +0 -103
  50. package/ARCHITECTURE.md +0 -133
  51. package/AUDIT_INSTRUCTIONS.md +0 -139
  52. package/RISKS.md +0 -215
  53. package/SKILLS.md +0 -55
  54. package/STYLE_GUIDE.md +0 -610
  55. package/USER_JOURNEYS.md +0 -215
  56. package/script/Deploy.s.sol +0 -124
  57. package/script/DeployPeriphery.s.sol +0 -354
  58. package/slither-ci.config.json +0 -10
  59. package/test/AuditFixes.t.sol +0 -808
  60. package/test/ComprehensiveInvariant.t.sol +0 -306
  61. package/test/CoreExploitTests.t.sol +0 -2741
  62. package/test/EconomicSimulation.t.sol +0 -348
  63. package/test/EntryPointPermutations.t.sol +0 -684
  64. package/test/FlashLoanAttacks.t.sol +0 -797
  65. package/test/PermissionEscalation.t.sol +0 -711
  66. package/test/PermissionsInvariant.t.sol +0 -403
  67. package/test/RulesetTransitions.t.sol +0 -713
  68. package/test/SplitLoopTests.t.sol +0 -752
  69. package/test/TestAccessToFunds.sol +0 -2683
  70. package/test/TestAuditResponseDesignProofs.sol +0 -434
  71. package/test/TestCashOut.sol +0 -198
  72. package/test/TestCashOutCountFor.sol +0 -271
  73. package/test/TestCashOutHooks.sol +0 -351
  74. package/test/TestCashOutTimingEdge.sol +0 -241
  75. package/test/TestDataHookFuzzing.sol +0 -524
  76. package/test/TestDurationUnderflow.sol +0 -233
  77. package/test/TestFeeFreeCashOutBypass.sol +0 -949
  78. package/test/TestFeeProcessingFailure.sol +0 -218
  79. package/test/TestFees.sol +0 -619
  80. package/test/TestForwardedTokenConsumption.sol +0 -425
  81. package/test/TestInterfaceSupport.sol +0 -81
  82. package/test/TestJBERC20Inheritance.sol +0 -103
  83. package/test/TestL2SequencerPriceFeed.sol +0 -292
  84. package/test/TestLaunchProject.sol +0 -188
  85. package/test/TestMetaTx.sol +0 -217
  86. package/test/TestMetadataOffsetOverflow.sol +0 -179
  87. package/test/TestMetadataParserLib.sol +0 -471
  88. package/test/TestMigrationHeldFees.sol +0 -255
  89. package/test/TestMintTokensOf.sol +0 -185
  90. package/test/TestMultiTerminalSurplus.sol +0 -348
  91. package/test/TestMultiTokenSurplus.sol +0 -202
  92. package/test/TestMultipleAccessLimits.sol +0 -664
  93. package/test/TestPayBurnRedeemFlow.sol +0 -195
  94. package/test/TestPayHooks.sol +0 -209
  95. package/test/TestPermissions.sol +0 -324
  96. package/test/TestPermissionsEdge.sol +0 -290
  97. package/test/TestPermit2DataHook.t.sol +0 -360
  98. package/test/TestPermit2Terminal.sol +0 -372
  99. package/test/TestRulesetQueueing.sol +0 -1025
  100. package/test/TestRulesetQueuingStress.sol +0 -806
  101. package/test/TestRulesetWeightCaching.sol +0 -178
  102. package/test/TestSplits.sol +0 -391
  103. package/test/TestTerminalMigration.sol +0 -274
  104. package/test/TestTerminalPreviewParity.sol +0 -208
  105. package/test/TestTokenFlow.sol +0 -191
  106. package/test/TestWeightCacheStaleAfterRejection.sol +0 -303
  107. package/test/WeirdTokenTests.t.sol +0 -817
  108. package/test/audit/CashOutReenterPay.t.sol +0 -501
  109. package/test/audit/CodexHeldFeeRounding.t.sol +0 -159
  110. package/test/audit/CodexMigrationFeeFailure.t.sol +0 -163
  111. package/test/audit/CrossTerminalSurplusSpoof.t.sol +0 -140
  112. package/test/audit/CycledSurplusAllowanceReset.t.sol +0 -184
  113. package/test/audit/FeeFreeSurplusLifecycle.t.sol +0 -399
  114. package/test/audit/FeeFreeSurplusStale.t.sol +0 -248
  115. package/test/audit/USDTVoidReturnCompat.t.sol +0 -525
  116. package/test/fork/TestChainlinkPriceFeedFork.sol +0 -254
  117. package/test/fork/TestSequencerPriceFeedFork.sol +0 -168
  118. package/test/fork/TestTerminalPreviewParityFork.sol +0 -108
  119. package/test/formal/BondingCurveProperties.t.sol +0 -420
  120. package/test/formal/FeeProperties.t.sol +0 -252
  121. package/test/invariants/Phase3DeepInvariant.t.sol +0 -412
  122. package/test/invariants/RulesetsInvariant.t.sol +0 -125
  123. package/test/invariants/TerminalStoreInvariant.t.sol +0 -227
  124. package/test/invariants/TokensInvariant.t.sol +0 -195
  125. package/test/invariants/handlers/ComprehensiveHandler.sol +0 -303
  126. package/test/invariants/handlers/EconomicHandler.sol +0 -377
  127. package/test/invariants/handlers/Phase3Handler.sol +0 -443
  128. package/test/invariants/handlers/RulesetsHandler.sol +0 -115
  129. package/test/invariants/handlers/TerminalStoreHandler.sol +0 -151
  130. package/test/invariants/handlers/TokensHandler.sol +0 -126
  131. package/test/regression/HoldFeesCashOutReserved.t.sol +0 -415
  132. package/test/regression/WeightCacheBoundary.t.sol +0 -291
  133. package/test/trees/JBController/burnTokensOf.tree +0 -9
  134. package/test/trees/JBController/claimTokensFor.tree +0 -5
  135. package/test/trees/JBController/deployERC20For.tree +0 -5
  136. package/test/trees/JBController/getRulesetOf.tree +0 -5
  137. package/test/trees/JBController/launchProjectFor.tree +0 -12
  138. package/test/trees/JBController/launchRulesetsFor.tree +0 -8
  139. package/test/trees/JBController/migrateController.tree +0 -12
  140. package/test/trees/JBController/mintTokensOf.tree +0 -12
  141. package/test/trees/JBController/payReservedTokenToTerminal.tree +0 -8
  142. package/test/trees/JBController/receiveMigrationFrom.tree +0 -4
  143. package/test/trees/JBController/sendReservedTokensToSplitsOf.tree +0 -12
  144. package/test/trees/JBController/setMetadataOf.tree +0 -5
  145. package/test/trees/JBController/setSplitGroupsOf.tree +0 -5
  146. package/test/trees/JBController/setTokenFor.tree +0 -5
  147. package/test/trees/JBController/transferCreditsFrom.tree +0 -8
  148. package/test/trees/JBDirectory/primaryTerminalOf.tree +0 -8
  149. package/test/trees/JBDirectory/setControllerOf.tree +0 -11
  150. package/test/trees/JBDirectory/setPrimaryTerminalOf.tree +0 -15
  151. package/test/trees/JBDirectory/setTerminalsOf.tree +0 -11
  152. package/test/trees/JBERC20/initialize.tree +0 -7
  153. package/test/trees/JBERC20/name.tree +0 -5
  154. package/test/trees/JBERC20/nonces.tree +0 -5
  155. package/test/trees/JBERC20/symbol.tree +0 -5
  156. package/test/trees/JBFeelessAddresses/setFeelessAddress.tree +0 -5
  157. package/test/trees/JBFeelessAddresses/supportsInterface.tree +0 -5
  158. package/test/trees/JBFundAccessLimits/payoutLimitOf.tree +0 -5
  159. package/test/trees/JBFundAccessLimits/payoutLimitsOf.tree +0 -8
  160. package/test/trees/JBFundAccessLimits/setFundAccessLimitsFor.tree +0 -18
  161. package/test/trees/JBFundAccessLimits/surplusAllowanceOf.tree +0 -5
  162. package/test/trees/JBFundAccessLimits/surplusAllowancesOf.tree +0 -8
  163. package/test/trees/JBMetadataResolver/getDataFor.tree +0 -8
  164. package/test/trees/JBMultiTerminal/accountingContextsOf.tree +0 -5
  165. package/test/trees/JBMultiTerminal/addAccountingContextsFor.tree +0 -10
  166. package/test/trees/JBMultiTerminal/addToBalanceOf.tree +0 -23
  167. package/test/trees/JBMultiTerminal/cashOutTokensOf.tree +0 -23
  168. package/test/trees/JBMultiTerminal/executePayout.tree +0 -32
  169. package/test/trees/JBMultiTerminal/executeProcessFee.tree +0 -14
  170. package/test/trees/JBMultiTerminal/migrateBalanceOf.tree +0 -12
  171. package/test/trees/JBMultiTerminal/pay.tree +0 -23
  172. package/test/trees/JBMultiTerminal/processHeldFeesOf.tree +0 -8
  173. package/test/trees/JBMultiTerminal/sendPayoutsOf.tree +0 -34
  174. package/test/trees/JBMultiTerminal/useAllowanceOf.tree +0 -16
  175. package/test/trees/JBPermissions/hasPermission.tree +0 -8
  176. package/test/trees/JBPermissions/hasPermissions.tree +0 -8
  177. package/test/trees/JBPermissions/setPermissionsFor.tree +0 -5
  178. package/test/trees/JBPrices/addPriceFeedFor.tree +0 -14
  179. package/test/trees/JBPrices/pricePerUnitOf.tree +0 -11
  180. package/test/trees/JBProjects/createFor.tree +0 -11
  181. package/test/trees/JBProjects/setTokenUriResolver.tree +0 -5
  182. package/test/trees/JBProjects/supportsInterface.tree +0 -9
  183. package/test/trees/JBProjects/tokenURI.tree +0 -5
  184. package/test/trees/JBRulesets/currentApprovalStatusForLatestRulesetOf.tree +0 -8
  185. package/test/trees/JBRulesets/currentOf.tree +0 -12
  186. package/test/trees/JBRulesets/getRulesetOf.tree +0 -5
  187. package/test/trees/JBRulesets/latestQueuedRulesetOf.tree +0 -10
  188. package/test/trees/JBRulesets/rulesetsOf.tree +0 -11
  189. package/test/trees/JBRulesets/upcomingRulesetOf.tree +0 -20
  190. package/test/trees/JBRulesets/updateRulesetWeightCache.tree +0 -5
  191. package/test/trees/JBSplits/setSplitGroupsOf.tree +0 -17
  192. package/test/trees/JBSplits/splitsOf.tree +0 -5
  193. package/test/trees/JBTerminalStore/currentReclaimableSurplusOf.tree +0 -16
  194. package/test/trees/JBTerminalStore/currentSurplusOf.tree +0 -25
  195. package/test/trees/JBTerminalStore/currentTotalSurplusOf.tree +0 -5
  196. package/test/trees/JBTerminalStore/recordCashOutsFor.tree +0 -16
  197. package/test/trees/JBTerminalStore/recordPaymentFrom.tree +0 -14
  198. package/test/trees/JBTerminalStore/recordPayoutFor.tree +0 -10
  199. package/test/trees/JBTerminalStore/recordTerminalMigration.tree +0 -5
  200. package/test/trees/JBTerminalStore/recordUsedAllowanceOf.tree +0 -10
  201. package/test/trees/JBTokens/burnFrom.tree +0 -10
  202. package/test/trees/JBTokens/claimTokensFor.tree +0 -10
  203. package/test/trees/JBTokens/deployERC20For.tree +0 -12
  204. package/test/trees/JBTokens/mintFor.tree +0 -10
  205. package/test/trees/JBTokens/setTokenFor.tree +0 -11
  206. package/test/trees/JBTokens/totalBalanceOf.tree +0 -5
  207. package/test/trees/JBTokens/totalSupplyOf.tree +0 -5
  208. package/test/trees/JBTokens/transferCreditsFrom.tree +0 -8
  209. package/test/trees/mintTokensOf.tree +0 -12
  210. package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +0 -223
  211. package/test/units/static/JBController/JBControllerSetup.sol +0 -50
  212. package/test/units/static/JBController/TestBurnTokensOf.sol +0 -114
  213. package/test/units/static/JBController/TestClaimTokensFor.sol +0 -63
  214. package/test/units/static/JBController/TestDeployErc20For.sol +0 -86
  215. package/test/units/static/JBController/TestLaunchProjectFor.sol +0 -302
  216. package/test/units/static/JBController/TestLaunchRulesetsFor.sol +0 -342
  217. package/test/units/static/JBController/TestMigrateController.sol +0 -157
  218. package/test/units/static/JBController/TestMintTokensOfUnits.sol +0 -111
  219. package/test/units/static/JBController/TestOmnichainRulesetOperator.sol +0 -324
  220. package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +0 -74
  221. package/test/units/static/JBController/TestPreviewMintOf.sol +0 -117
  222. package/test/units/static/JBController/TestReceiveMigrationFrom.sol +0 -99
  223. package/test/units/static/JBController/TestRulesetViews.sol +0 -225
  224. package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +0 -615
  225. package/test/units/static/JBController/TestSetSplitGroupsOf.sol +0 -68
  226. package/test/units/static/JBController/TestSetTokenFor.sol +0 -239
  227. package/test/units/static/JBController/TestSetUriOf.sol +0 -57
  228. package/test/units/static/JBController/TestTransferCreditsFrom.sol +0 -169
  229. package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +0 -211
  230. package/test/units/static/JBDirectory/JBDirectorySetup.sol +0 -26
  231. package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +0 -126
  232. package/test/units/static/JBDirectory/TestSetControllerOf.sol +0 -183
  233. package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +0 -104
  234. package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +0 -179
  235. package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +0 -137
  236. package/test/units/static/JBERC20/JBERC20Setup.sol +0 -34
  237. package/test/units/static/JBERC20/SigUtils.sol +0 -36
  238. package/test/units/static/JBERC20/TestInitialize.sol +0 -60
  239. package/test/units/static/JBERC20/TestName.sol +0 -30
  240. package/test/units/static/JBERC20/TestNonces.sol +0 -62
  241. package/test/units/static/JBERC20/TestSymbol.sol +0 -31
  242. package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +0 -22
  243. package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +0 -30
  244. package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +0 -35
  245. package/test/units/static/JBFees/TestFeesFuzz.sol +0 -79
  246. package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +0 -16
  247. package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +0 -71
  248. package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +0 -24
  249. package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +0 -163
  250. package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +0 -59
  251. package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +0 -101
  252. package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +0 -189
  253. package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +0 -64
  254. package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +0 -102
  255. package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +0 -90
  256. package/test/units/static/JBMetadataResolver/TestMetadataResolverEdgeCases.sol +0 -247
  257. package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +0 -229
  258. package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +0 -50
  259. package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +0 -72
  260. package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +0 -289
  261. package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +0 -474
  262. package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +0 -624
  263. package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +0 -578
  264. package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +0 -202
  265. package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +0 -222
  266. package/test/units/static/JBMultiTerminal/TestPay.sol +0 -604
  267. package/test/units/static/JBMultiTerminal/TestPreviewCashOutFrom.sol +0 -117
  268. package/test/units/static/JBMultiTerminal/TestPreviewPayFor.sol +0 -114
  269. package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +0 -228
  270. package/test/units/static/JBMultiTerminal/TestSelfPayRevert.sol +0 -55
  271. package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +0 -257
  272. package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +0 -611
  273. package/test/units/static/JBPermissions/JBPermissionsSetup.sol +0 -20
  274. package/test/units/static/JBPermissions/TestHasPermission.sol +0 -50
  275. package/test/units/static/JBPermissions/TestHasPermissions.sol +0 -93
  276. package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +0 -64
  277. package/test/units/static/JBPrices/JBPricesSetup.sol +0 -32
  278. package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +0 -107
  279. package/test/units/static/JBPrices/TestPricePerUnitOf.sol +0 -132
  280. package/test/units/static/JBPrices/TestPrices.sol +0 -265
  281. package/test/units/static/JBProjects/JBProjectsSetup.sol +0 -22
  282. package/test/units/static/JBProjects/TestCreateFor.sol +0 -71
  283. package/test/units/static/JBProjects/TestInitialProject.sol +0 -21
  284. package/test/units/static/JBProjects/TestInterfaces.sol +0 -26
  285. package/test/units/static/JBProjects/TestSetResolver.sol +0 -37
  286. package/test/units/static/JBProjects/TestTokenUri.sol +0 -40
  287. package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +0 -108
  288. package/test/units/static/JBRulesets/JBRulesetsSetup.sol +0 -24
  289. package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +0 -265
  290. package/test/units/static/JBRulesets/TestCurrentOf.sol +0 -242
  291. package/test/units/static/JBRulesets/TestGetRulesetOf.sol +0 -100
  292. package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +0 -260
  293. package/test/units/static/JBRulesets/TestRulesets.sol +0 -632
  294. package/test/units/static/JBRulesets/TestRulesetsOf.sol +0 -37
  295. package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +0 -522
  296. package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +0 -96
  297. package/test/units/static/JBSplits/JBSplitsSetup.sol +0 -26
  298. package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +0 -552
  299. package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +0 -377
  300. package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +0 -267
  301. package/test/units/static/JBSplits/TestSplitsOf.sol +0 -24
  302. package/test/units/static/JBSplits/TestSplitsPacking.sol +0 -36
  303. package/test/units/static/JBSurplus/TestSurplusFuzz.sol +0 -160
  304. package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +0 -45
  305. package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +0 -536
  306. package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +0 -463
  307. package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +0 -135
  308. package/test/units/static/JBTerminalStore/TestPreviewCashOutFrom.sol +0 -476
  309. package/test/units/static/JBTerminalStore/TestPreviewPayFrom.sol +0 -494
  310. package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +0 -652
  311. package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +0 -744
  312. package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +0 -289
  313. package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +0 -138
  314. package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +0 -415
  315. package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +0 -219
  316. package/test/units/static/JBTokens/JBTokensSetup.sol +0 -32
  317. package/test/units/static/JBTokens/TestBurnFrom.sol +0 -107
  318. package/test/units/static/JBTokens/TestClaimTokensFor.sol +0 -110
  319. package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +0 -92
  320. package/test/units/static/JBTokens/TestMintFor.sol +0 -100
  321. package/test/units/static/JBTokens/TestSetTokenFor.sol +0 -98
  322. package/test/units/static/JBTokens/TestTotalBalanceOf.sol +0 -65
  323. package/test/units/static/JBTokens/TestTotalSupplyOf.sol +0 -56
  324. package/test/units/static/JBTokens/TestTransferCreditsFrom.sol +0 -56
@@ -1,711 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity ^0.8.6;
3
-
4
- import {TestBaseWorkflow} from "./helpers/TestBaseWorkflow.sol";
5
- import {JBPermissions} from "../src/JBPermissions.sol";
6
- import {IJBRulesetApprovalHook} from "../src/interfaces/IJBRulesetApprovalHook.sol";
7
- import {JBConstants} from "../src/libraries/JBConstants.sol";
8
- import {JBRulesetMetadataResolver} from "../src/libraries/JBRulesetMetadataResolver.sol";
9
- import {JBCurrencyAmount} from "../src/structs/JBCurrencyAmount.sol";
10
- import {JBFundAccessLimitGroup} from "../src/structs/JBFundAccessLimitGroup.sol";
11
- import {JBPermissionsData} from "../src/structs/JBPermissionsData.sol";
12
- import {JBRuleset} from "../src/structs/JBRuleset.sol";
13
- import {JBRulesetConfig} from "../src/structs/JBRulesetConfig.sol";
14
- import {JBRulesetMetadata} from "../src/structs/JBRulesetMetadata.sol";
15
- import {JBSplitGroup} from "../src/structs/JBSplitGroup.sol";
16
- import {JBTerminalConfig} from "../src/structs/JBTerminalConfig.sol";
17
- import {JBPermissionIds} from "@bananapus/permission-ids-v6/src/JBPermissionIds.sol";
18
- import {JBAccountingContext} from "../src/structs/JBAccountingContext.sol";
19
-
20
- /// @notice Tests for permission system correctness: ROOT restrictions, wildcard, boundary IDs, escalation prevention.
21
- contract PermissionEscalation_Local is TestBaseWorkflow {
22
- using JBRulesetMetadataResolver for JBRuleset;
23
-
24
- uint256 public projectId2;
25
- uint256 public projectId3;
26
- address public projectOwner;
27
- address public alice;
28
- address public bob;
29
- address public charlie;
30
-
31
- function setUp() public override {
32
- super.setUp();
33
- projectOwner = multisig();
34
- alice = address(0xA11CE);
35
- bob = address(0xB0B);
36
- charlie = address(0xC4A7);
37
-
38
- // Launch fee collector project (#1)
39
- _launchFeeProject();
40
-
41
- // Launch test project #2
42
- projectId2 = _launchSimpleProject("project2");
43
-
44
- // Launch test project #3
45
- projectId3 = _launchSimpleProject("project3");
46
-
47
- // Give Alice ROOT on project 2
48
- uint8[] memory rootPerms = new uint8[](1);
49
- rootPerms[0] = JBPermissionIds.ROOT;
50
- vm.prank(projectOwner);
51
- jbPermissions()
52
- .setPermissionsFor(
53
- projectOwner,
54
- // forge-lint: disable-next-line(unsafe-typecast)
55
- JBPermissionsData({operator: alice, projectId: uint64(projectId2), permissionIds: rootPerms})
56
- );
57
- }
58
-
59
- // ═══════════════════════════════════════════════════════════════════
60
- // Helpers
61
- // ═══════════════════════════════════════════════════════════════════
62
-
63
- function _launchFeeProject() internal {
64
- JBRulesetConfig[] memory feeRulesetConfig = new JBRulesetConfig[](1);
65
- feeRulesetConfig[0].mustStartAtOrAfter = 0;
66
- feeRulesetConfig[0].duration = 0;
67
- feeRulesetConfig[0].weight = 1000e18;
68
- feeRulesetConfig[0].weightCutPercent = 0;
69
- feeRulesetConfig[0].approvalHook = IJBRulesetApprovalHook(address(0));
70
- feeRulesetConfig[0].metadata = JBRulesetMetadata({
71
- reservedPercent: 0,
72
- cashOutTaxRate: 0,
73
- baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
74
- pausePay: false,
75
- pauseCreditTransfers: false,
76
- allowOwnerMinting: false,
77
- allowSetCustomToken: false,
78
- allowTerminalMigration: false,
79
- allowSetTerminals: false,
80
- ownerMustSendPayouts: false,
81
- allowSetController: false,
82
- allowAddAccountingContext: true,
83
- allowAddPriceFeed: false,
84
- holdFees: false,
85
- useTotalSurplusForCashOuts: false,
86
- useDataHookForPay: false,
87
- useDataHookForCashOut: false,
88
- dataHook: address(0),
89
- metadata: 0
90
- });
91
- feeRulesetConfig[0].splitGroups = new JBSplitGroup[](0);
92
- feeRulesetConfig[0].fundAccessLimitGroups = new JBFundAccessLimitGroup[](0);
93
-
94
- JBTerminalConfig[] memory terminalConfigurations = _defaultTerminalConfig();
95
-
96
- jbController()
97
- .launchProjectFor({
98
- owner: address(420),
99
- projectUri: "feeCollector",
100
- rulesetConfigurations: feeRulesetConfig,
101
- terminalConfigurations: terminalConfigurations,
102
- memo: ""
103
- });
104
- }
105
-
106
- function _launchSimpleProject(string memory uri) internal returns (uint256) {
107
- JBRulesetConfig[] memory rulesetConfig = new JBRulesetConfig[](1);
108
- rulesetConfig[0].mustStartAtOrAfter = 0;
109
- rulesetConfig[0].duration = 0;
110
- rulesetConfig[0].weight = 1000e18;
111
- rulesetConfig[0].weightCutPercent = 0;
112
- rulesetConfig[0].approvalHook = IJBRulesetApprovalHook(address(0));
113
- rulesetConfig[0].metadata = JBRulesetMetadata({
114
- reservedPercent: 0,
115
- cashOutTaxRate: 3000,
116
- baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
117
- pausePay: false,
118
- pauseCreditTransfers: false,
119
- allowOwnerMinting: true,
120
- allowSetCustomToken: true,
121
- allowTerminalMigration: false,
122
- allowSetTerminals: false,
123
- ownerMustSendPayouts: false,
124
- allowSetController: false,
125
- allowAddAccountingContext: true,
126
- allowAddPriceFeed: false,
127
- holdFees: false,
128
- useTotalSurplusForCashOuts: false,
129
- useDataHookForPay: false,
130
- useDataHookForCashOut: false,
131
- dataHook: address(0),
132
- metadata: 0
133
- });
134
- rulesetConfig[0].splitGroups = new JBSplitGroup[](0);
135
- rulesetConfig[0].fundAccessLimitGroups = new JBFundAccessLimitGroup[](0);
136
-
137
- return jbController()
138
- .launchProjectFor({
139
- owner: projectOwner,
140
- projectUri: uri,
141
- rulesetConfigurations: rulesetConfig,
142
- terminalConfigurations: _defaultTerminalConfig(),
143
- memo: ""
144
- });
145
- }
146
-
147
- function _defaultTerminalConfig() internal view returns (JBTerminalConfig[] memory) {
148
- JBTerminalConfig[] memory terminalConfigurations = new JBTerminalConfig[](1);
149
- JBAccountingContext[] memory tokensToAccept = new JBAccountingContext[](1);
150
- tokensToAccept[0] = JBAccountingContext({
151
- token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
152
- });
153
- terminalConfigurations[0] =
154
- JBTerminalConfig({terminal: jbMultiTerminal(), accountingContextsToAccept: tokensToAccept});
155
- return terminalConfigurations;
156
- }
157
-
158
- // ═══════════════════════════════════════════════════════════════════
159
- // Test 1: ROOT cannot set wildcard permissions (projectId=0)
160
- // ═══════════════════════════════════════════════════════════════════
161
-
162
- function test_rootOperator_cannotSetWildcardPermissions() public {
163
- // Alice has ROOT on project 2. She tries to grant Bob permissions at projectId=0 (wildcard).
164
- uint8[] memory perms = new uint8[](1);
165
- perms[0] = JBPermissionIds.CASH_OUT_TOKENS;
166
-
167
- vm.prank(alice);
168
- vm.expectRevert(
169
- abi.encodeWithSelector(
170
- JBPermissions.JBPermissions_Unauthorized.selector, projectOwner, alice, 0, JBPermissionIds.ROOT
171
- )
172
- );
173
- jbPermissions()
174
- .setPermissionsFor(projectOwner, JBPermissionsData({operator: bob, projectId: 0, permissionIds: perms}));
175
- }
176
-
177
- // ═══════════════════════════════════════════════════════════════════
178
- // Test 2: ROOT cannot grant ROOT to a third party
179
- // ═══════════════════════════════════════════════════════════════════
180
-
181
- function test_rootOperator_cannotGrantRoot() public {
182
- // Alice has ROOT on project 2. She tries to grant ROOT to Bob.
183
- uint8[] memory perms = new uint8[](1);
184
- perms[0] = JBPermissionIds.ROOT;
185
-
186
- vm.prank(alice);
187
- vm.expectRevert(
188
- abi.encodeWithSelector(
189
- JBPermissions.JBPermissions_Unauthorized.selector,
190
- projectOwner,
191
- alice,
192
- // forge-lint: disable-next-line(unsafe-typecast)
193
- uint64(projectId2),
194
- JBPermissionIds.ROOT
195
- )
196
- );
197
- jbPermissions()
198
- .setPermissionsFor(
199
- // forge-lint: disable-next-line(unsafe-typecast)
200
- projectOwner,
201
- // forge-lint: disable-next-line(unsafe-typecast)
202
- JBPermissionsData({operator: bob, projectId: uint64(projectId2), permissionIds: perms})
203
- );
204
- }
205
-
206
- // ═══════════════════════════════════════════════════════════════════
207
- // Test 3: ROOT CAN grant non-ROOT permissions (positive test)
208
- // ═══════════════════════════════════════════════════════════════════
209
-
210
- function test_rootOperator_canGrantNonRootPermissions() public {
211
- // Alice has ROOT on project 2. She grants Bob CASH_OUT_TOKENS.
212
- uint8[] memory perms = new uint8[](1);
213
- perms[0] = JBPermissionIds.CASH_OUT_TOKENS;
214
-
215
- vm.prank(alice);
216
- jbPermissions()
217
- .setPermissionsFor(
218
- // forge-lint: disable-next-line(unsafe-typecast)
219
- projectOwner,
220
- // forge-lint: disable-next-line(unsafe-typecast)
221
- JBPermissionsData({operator: bob, projectId: uint64(projectId2), permissionIds: perms})
222
- );
223
-
224
- // Verify Bob now has CASH_OUT_TOKENS
225
- bool hasPerm = jbPermissions()
226
- .hasPermission({
227
- operator: bob,
228
- account: projectOwner,
229
- projectId: projectId2,
230
- permissionId: JBPermissionIds.CASH_OUT_TOKENS,
231
- includeRoot: false,
232
- includeWildcardProjectId: false
233
- });
234
- assertTrue(hasPerm, "ROOT should be able to grant non-ROOT permissions");
235
- }
236
-
237
- // ═══════════════════════════════════════════════════════════════════
238
- // Test 4: Wildcard permission — applies cross-project
239
- // ═══════════════════════════════════════════════════════════════════
240
-
241
- function test_wildcardPermission_crossProject() public {
242
- // Owner grants Bob CASH_OUT_TOKENS at projectId=0 (wildcard)
243
- uint8[] memory perms = new uint8[](1);
244
- perms[0] = JBPermissionIds.CASH_OUT_TOKENS;
245
-
246
- vm.prank(projectOwner);
247
- jbPermissions()
248
- .setPermissionsFor(projectOwner, JBPermissionsData({operator: bob, projectId: 0, permissionIds: perms}));
249
-
250
- // Bob should have CASH_OUT_TOKENS for project 2 (via wildcard)
251
- bool hasPermProject2 = jbPermissions()
252
- .hasPermission({
253
- operator: bob,
254
- account: projectOwner,
255
- projectId: projectId2,
256
- permissionId: JBPermissionIds.CASH_OUT_TOKENS,
257
- includeRoot: false,
258
- includeWildcardProjectId: true
259
- });
260
- assertTrue(hasPermProject2, "Wildcard should apply to project 2");
261
-
262
- // Bob should have CASH_OUT_TOKENS for project 3 (via wildcard)
263
- bool hasPermProject3 = jbPermissions()
264
- .hasPermission({
265
- operator: bob,
266
- account: projectOwner,
267
- projectId: projectId3,
268
- permissionId: JBPermissionIds.CASH_OUT_TOKENS,
269
- includeRoot: false,
270
- includeWildcardProjectId: true
271
- });
272
- assertTrue(hasPermProject3, "Wildcard should apply to project 3");
273
- }
274
-
275
- // ═══════════════════════════════════════════════════════════════════
276
- // Test 5: Permission revocation is immediate
277
- // ═══════════════════════════════════════════════════════════════════
278
-
279
- function test_permissionRevocation_immediate() public {
280
- // Grant Bob CASH_OUT_TOKENS on project 2
281
- uint8[] memory perms = new uint8[](1);
282
- perms[0] = JBPermissionIds.CASH_OUT_TOKENS;
283
-
284
- vm.prank(projectOwner);
285
- jbPermissions()
286
- .setPermissionsFor(
287
- // forge-lint: disable-next-line(unsafe-typecast)
288
- projectOwner,
289
- // forge-lint: disable-next-line(unsafe-typecast)
290
- JBPermissionsData({operator: bob, projectId: uint64(projectId2), permissionIds: perms})
291
- );
292
-
293
- // Verify Bob has it
294
- assertTrue(
295
- jbPermissions()
296
- .hasPermission({
297
- operator: bob,
298
- account: projectOwner,
299
- projectId: projectId2,
300
- permissionId: JBPermissionIds.CASH_OUT_TOKENS,
301
- includeRoot: false,
302
- includeWildcardProjectId: false
303
- }),
304
- "Bob should have CASH_OUT_TOKENS"
305
- );
306
-
307
- // Revoke by setting empty permissions
308
- uint8[] memory emptyPerms = new uint8[](0);
309
-
310
- vm.prank(projectOwner);
311
- jbPermissions()
312
- .setPermissionsFor(
313
- projectOwner,
314
- // forge-lint: disable-next-line(unsafe-typecast)
315
- JBPermissionsData({operator: bob, projectId: uint64(projectId2), permissionIds: emptyPerms})
316
- );
317
-
318
- // Immediately verify Bob lost it
319
- assertFalse(
320
- jbPermissions()
321
- .hasPermission({
322
- operator: bob,
323
- account: projectOwner,
324
- projectId: projectId2,
325
- permissionId: JBPermissionIds.CASH_OUT_TOKENS,
326
- includeRoot: false,
327
- includeWildcardProjectId: false
328
- }),
329
- "Revocation should be immediate"
330
- );
331
- }
332
-
333
- // ═══════════════════════════════════════════════════════════════════
334
- // Test 6: Bit 255 (ROOT) works. Bit 256 reverts.
335
- // ═══════════════════════════════════════════════════════════════════
336
-
337
- function test_permission_bit255_boundary() public {
338
- // Permission 255 should work (max valid ID)
339
- uint8[] memory perms = new uint8[](1);
340
- perms[0] = 255;
341
-
342
- vm.prank(projectOwner);
343
- jbPermissions()
344
- .setPermissionsFor(
345
- // forge-lint: disable-next-line(unsafe-typecast)
346
- projectOwner,
347
- // forge-lint: disable-next-line(unsafe-typecast)
348
- JBPermissionsData({operator: bob, projectId: uint64(projectId2), permissionIds: perms})
349
- );
350
-
351
- bool hasPerm = jbPermissions()
352
- .hasPermission({
353
- operator: bob,
354
- account: projectOwner,
355
- projectId: projectId2,
356
- permissionId: 255,
357
- includeRoot: false,
358
- includeWildcardProjectId: false
359
- });
360
- assertTrue(hasPerm, "Permission ID 255 should work");
361
-
362
- // Permission 256 should revert (out of bounds)
363
- vm.expectRevert(abi.encodeWithSelector(JBPermissions.JBPermissions_PermissionIdOutOfBounds.selector, 256));
364
- jbPermissions()
365
- .hasPermission({
366
- operator: bob,
367
- account: projectOwner,
368
- projectId: projectId2,
369
- permissionId: 256,
370
- includeRoot: false,
371
- includeWildcardProjectId: false
372
- });
373
- }
374
-
375
- // ═══════════════════════════════════════════════════════════════════
376
- // Test 7: Permission ID 0 reverts
377
- // ═══════════════════════════════════════════════════════════════════
378
-
379
- function test_permission_bit0_rejected() public {
380
- // Permission 0 is invalid
381
- uint8[] memory perms = new uint8[](1);
382
- perms[0] = 0;
383
-
384
- vm.prank(projectOwner);
385
- vm.expectRevert(abi.encodeWithSelector(JBPermissions.JBPermissions_NoZeroPermission.selector));
386
- jbPermissions()
387
- .setPermissionsFor(
388
- // forge-lint: disable-next-line(unsafe-typecast)
389
- projectOwner,
390
- // forge-lint: disable-next-line(unsafe-typecast)
391
- JBPermissionsData({operator: bob, projectId: uint64(projectId2), permissionIds: perms})
392
- );
393
- }
394
-
395
- // ═══════════════════════════════════════════════════════════════════
396
- // Test 8: Bob can't cashOut Alice's tokens without permission
397
- // ═══════════════════════════════════════════════════════════════════
398
-
399
- function test_permissionedOperation_cashOut_requiresPermission() public {
400
- // Give Alice tokens by paying
401
- vm.deal(alice, 10 ether);
402
- vm.prank(alice);
403
- uint256 tokens = jbMultiTerminal().pay{value: 10 ether}({
404
- projectId: projectId2,
405
- token: JBConstants.NATIVE_TOKEN,
406
- amount: 10 ether,
407
- beneficiary: alice,
408
- minReturnedTokens: 0,
409
- memo: "",
410
- metadata: new bytes(0)
411
- });
412
-
413
- // Bob tries to cash out Alice's tokens without permission
414
- vm.prank(bob);
415
- vm.expectRevert();
416
- jbMultiTerminal()
417
- .cashOutTokensOf({
418
- holder: alice,
419
- projectId: projectId2,
420
- cashOutCount: tokens,
421
- tokenToReclaim: JBConstants.NATIVE_TOKEN,
422
- minTokensReclaimed: 0,
423
- beneficiary: payable(bob),
424
- metadata: new bytes(0)
425
- });
426
- }
427
-
428
- // ═══════════════════════════════════════════════════════════════════
429
- // Test 9: ownerMustSendPayouts flag enforcement
430
- // ═══════════════════════════════════════════════════════════════════
431
-
432
- function test_permissionedOperation_sendPayouts_ownerMustSend() public {
433
- // Launch project with ownerMustSendPayouts = true
434
- JBRulesetConfig[] memory rulesetConfig = new JBRulesetConfig[](1);
435
- rulesetConfig[0].mustStartAtOrAfter = 0;
436
- rulesetConfig[0].duration = 0;
437
- rulesetConfig[0].weight = 1000e18;
438
- rulesetConfig[0].weightCutPercent = 0;
439
- rulesetConfig[0].approvalHook = IJBRulesetApprovalHook(address(0));
440
- rulesetConfig[0].metadata = JBRulesetMetadata({
441
- reservedPercent: 0,
442
- cashOutTaxRate: 0,
443
- baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
444
- pausePay: false,
445
- pauseCreditTransfers: false,
446
- allowOwnerMinting: true,
447
- allowSetCustomToken: true,
448
- allowTerminalMigration: false,
449
- allowSetTerminals: false,
450
- ownerMustSendPayouts: true, // KEY
451
- allowSetController: false,
452
- allowAddAccountingContext: true,
453
- allowAddPriceFeed: false,
454
- holdFees: false,
455
- useTotalSurplusForCashOuts: false,
456
- useDataHookForPay: false,
457
- useDataHookForCashOut: false,
458
- dataHook: address(0),
459
- metadata: 0
460
- });
461
- rulesetConfig[0].splitGroups = new JBSplitGroup[](0);
462
-
463
- JBCurrencyAmount[] memory payoutLimits = new JBCurrencyAmount[](1);
464
- payoutLimits[0] = JBCurrencyAmount({amount: 10 ether, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))});
465
- JBFundAccessLimitGroup[] memory fundAccessLimitGroups = new JBFundAccessLimitGroup[](1);
466
- fundAccessLimitGroups[0] = JBFundAccessLimitGroup({
467
- terminal: address(jbMultiTerminal()),
468
- token: JBConstants.NATIVE_TOKEN,
469
- payoutLimits: payoutLimits,
470
- surplusAllowances: new JBCurrencyAmount[](0)
471
- });
472
- rulesetConfig[0].fundAccessLimitGroups = fundAccessLimitGroups;
473
-
474
- uint256 pid = jbController()
475
- .launchProjectFor({
476
- owner: projectOwner,
477
- projectUri: "ownerMustPayTest",
478
- rulesetConfigurations: rulesetConfig,
479
- terminalConfigurations: _defaultTerminalConfig(),
480
- memo: ""
481
- });
482
-
483
- // Fund the project
484
- vm.deal(address(0xBA1E), 20 ether);
485
- vm.prank(address(0xBA1E));
486
- jbMultiTerminal().pay{value: 20 ether}({
487
- projectId: pid,
488
- token: JBConstants.NATIVE_TOKEN,
489
- amount: 20 ether,
490
- beneficiary: address(0xBA1E),
491
- minReturnedTokens: 0,
492
- memo: "",
493
- metadata: new bytes(0)
494
- });
495
-
496
- // Grant Bob SEND_PAYOUTS permission
497
- uint8[] memory perms = new uint8[](1);
498
- perms[0] = JBPermissionIds.SEND_PAYOUTS;
499
- vm.prank(projectOwner);
500
- jbPermissions()
501
- .setPermissionsFor(
502
- // forge-lint: disable-next-line(unsafe-typecast)
503
- projectOwner,
504
- // forge-lint: disable-next-line(unsafe-typecast)
505
- JBPermissionsData({operator: bob, projectId: uint64(pid), permissionIds: perms})
506
- );
507
-
508
- // Charlie (no permission) tries to send payouts — should fail because ownerMustSendPayouts
509
- // requires SEND_PAYOUTS permission
510
- vm.prank(charlie);
511
- vm.expectRevert();
512
- jbMultiTerminal()
513
- .sendPayoutsOf({
514
- projectId: pid,
515
- token: JBConstants.NATIVE_TOKEN,
516
- amount: 5 ether,
517
- currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
518
- minTokensPaidOut: 0
519
- });
520
-
521
- // Bob (with SEND_PAYOUTS permission) CAN send payouts
522
- vm.prank(bob);
523
- jbMultiTerminal()
524
- .sendPayoutsOf({
525
- projectId: pid,
526
- token: JBConstants.NATIVE_TOKEN,
527
- amount: 5 ether,
528
- currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
529
- minTokensPaidOut: 0
530
- });
531
- }
532
-
533
- // ═══════════════════════════════════════════════════════════════════
534
- // Test 10: ROOT on project 2 has no power over project 3
535
- // ═══════════════════════════════════════════════════════════════════
536
-
537
- function test_permission_rootOnProject_doesNotAffectOtherProject() public view {
538
- // Alice has ROOT on project 2 (from setUp)
539
- // Alice should NOT have any permissions on project 3
540
- bool hasPermOnProject3 = jbPermissions()
541
- .hasPermission({
542
- operator: alice,
543
- account: projectOwner,
544
- projectId: projectId3,
545
- permissionId: JBPermissionIds.ROOT,
546
- includeRoot: true,
547
- includeWildcardProjectId: false
548
- });
549
- assertFalse(hasPermOnProject3, "ROOT on project 2 must not grant power over project 3");
550
-
551
- bool hasCashOutOnProject3 = jbPermissions()
552
- .hasPermission({
553
- operator: alice,
554
- account: projectOwner,
555
- projectId: projectId3,
556
- permissionId: JBPermissionIds.CASH_OUT_TOKENS,
557
- includeRoot: true,
558
- includeWildcardProjectId: false
559
- });
560
- assertFalse(hasCashOutOnProject3, "ROOT on project 2 must not grant CASH_OUT on project 3");
561
- }
562
-
563
- // ═══════════════════════════════════════════════════════════════════
564
- // Test 11: Double set overwrites previous (not additive)
565
- // ═══════════════════════════════════════════════════════════════════
566
-
567
- function test_permission_doubleSet_overwritesPrevious() public {
568
- // Grant Bob CASH_OUT_TOKENS + BURN_TOKENS
569
- uint8[] memory perms1 = new uint8[](2);
570
- perms1[0] = JBPermissionIds.CASH_OUT_TOKENS;
571
- perms1[1] = JBPermissionIds.BURN_TOKENS;
572
-
573
- vm.prank(projectOwner);
574
- jbPermissions()
575
- .setPermissionsFor(
576
- // forge-lint: disable-next-line(unsafe-typecast)
577
- projectOwner,
578
- // forge-lint: disable-next-line(unsafe-typecast)
579
- JBPermissionsData({operator: bob, projectId: uint64(projectId2), permissionIds: perms1})
580
- );
581
-
582
- assertTrue(
583
- jbPermissions()
584
- .hasPermission({
585
- operator: bob,
586
- account: projectOwner,
587
- projectId: projectId2,
588
- permissionId: JBPermissionIds.CASH_OUT_TOKENS,
589
- includeRoot: false,
590
- includeWildcardProjectId: false
591
- }),
592
- "Bob should have CASH_OUT_TOKENS"
593
- );
594
- assertTrue(
595
- jbPermissions()
596
- .hasPermission({
597
- operator: bob,
598
- account: projectOwner,
599
- projectId: projectId2,
600
- permissionId: JBPermissionIds.BURN_TOKENS,
601
- includeRoot: false,
602
- includeWildcardProjectId: false
603
- }),
604
- "Bob should have BURN_TOKENS"
605
- );
606
-
607
- // Now set ONLY MINT_TOKENS — should replace all previous
608
- uint8[] memory perms2 = new uint8[](1);
609
- perms2[0] = JBPermissionIds.MINT_TOKENS;
610
-
611
- vm.prank(projectOwner);
612
- jbPermissions()
613
- .setPermissionsFor(
614
- // forge-lint: disable-next-line(unsafe-typecast)
615
- projectOwner,
616
- // forge-lint: disable-next-line(unsafe-typecast)
617
- JBPermissionsData({operator: bob, projectId: uint64(projectId2), permissionIds: perms2})
618
- );
619
-
620
- // Bob should only have MINT_TOKENS, not the previous ones
621
- assertTrue(
622
- jbPermissions()
623
- .hasPermission({
624
- operator: bob,
625
- account: projectOwner,
626
- projectId: projectId2,
627
- permissionId: JBPermissionIds.MINT_TOKENS,
628
- includeRoot: false,
629
- includeWildcardProjectId: false
630
- }),
631
- "Bob should now have MINT_TOKENS"
632
- );
633
- assertFalse(
634
- jbPermissions()
635
- .hasPermission({
636
- operator: bob,
637
- account: projectOwner,
638
- projectId: projectId2,
639
- permissionId: JBPermissionIds.CASH_OUT_TOKENS,
640
- includeRoot: false,
641
- includeWildcardProjectId: false
642
- }),
643
- "Bob should no longer have CASH_OUT_TOKENS (overwritten)"
644
- );
645
- assertFalse(
646
- jbPermissions()
647
- .hasPermission({
648
- operator: bob,
649
- account: projectOwner,
650
- projectId: projectId2,
651
- permissionId: JBPermissionIds.BURN_TOKENS,
652
- includeRoot: false,
653
- includeWildcardProjectId: false
654
- }),
655
- "Bob should no longer have BURN_TOKENS (overwritten)"
656
- );
657
- }
658
-
659
- // ═══════════════════════════════════════════════════════════════════
660
- // Test 12: ERC2771 meta-tx uses correct msg.sender for permissions
661
- // ═══════════════════════════════════════════════════════════════════
662
-
663
- function test_rootPermission_trustedForwarder() public {
664
- // Grant Bob ROOT on project 2
665
- uint8[] memory perms = new uint8[](1);
666
- perms[0] = JBPermissionIds.CASH_OUT_TOKENS;
667
-
668
- vm.prank(projectOwner);
669
- jbPermissions()
670
- .setPermissionsFor(
671
- // forge-lint: disable-next-line(unsafe-typecast)
672
- projectOwner,
673
- // forge-lint: disable-next-line(unsafe-typecast)
674
- JBPermissionsData({operator: bob, projectId: uint64(projectId2), permissionIds: perms})
675
- );
676
-
677
- // Call from trusted forwarder with Bob appended as sender
678
- // The permission check should use Bob's address, not the forwarder
679
- address forwarder = trustedForwarder();
680
-
681
- // Verify the forwarder is set up correctly
682
- assertTrue(forwarder != address(0), "Trusted forwarder should be set");
683
-
684
- // Direct call should return true
685
- bool hasPerm = jbPermissions()
686
- .hasPermission({
687
- operator: bob,
688
- account: projectOwner,
689
- projectId: projectId2,
690
- permissionId: JBPermissionIds.CASH_OUT_TOKENS,
691
- includeRoot: false,
692
- includeWildcardProjectId: false
693
- });
694
- assertTrue(hasPerm, "Bob should have CASH_OUT_TOKENS via direct call");
695
-
696
- // Verify that permission checking respects msg.sender context
697
- // Charlie (unpermissioned) cannot use Bob's permissions
698
- bool charlieHasPerm = jbPermissions()
699
- .hasPermission({
700
- operator: charlie,
701
- account: projectOwner,
702
- projectId: projectId2,
703
- permissionId: JBPermissionIds.CASH_OUT_TOKENS,
704
- includeRoot: false,
705
- includeWildcardProjectId: false
706
- });
707
- assertFalse(charlieHasPerm, "Charlie should NOT have Bob's CASH_OUT_TOKENS");
708
- }
709
-
710
- receive() external payable {}
711
- }