@bananapus/core-v6 0.0.37 → 0.0.38

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 (287) hide show
  1. package/foundry.lock +1 -7
  2. package/foundry.toml +1 -1
  3. package/package.json +19 -7
  4. package/src/JBController.sol +19 -1
  5. package/src/JBMultiTerminal.sol +68 -34
  6. package/src/JBTerminalStore.sol +6 -6
  7. package/src/interfaces/IJBController.sol +4 -1
  8. package/src/libraries/JBFees.sol +47 -9
  9. package/src/libraries/JBPayoutSplitGroupLib.sol +2 -2
  10. package/src/periphery/JBMatchingPriceFeed.sol +1 -1
  11. package/test/mock/MockMaliciousBeneficiary.sol +15 -15
  12. package/ADMINISTRATION.md +0 -103
  13. package/ARCHITECTURE.md +0 -133
  14. package/AUDIT_INSTRUCTIONS.md +0 -139
  15. package/RISKS.md +0 -215
  16. package/SKILLS.md +0 -55
  17. package/STYLE_GUIDE.md +0 -610
  18. package/USER_JOURNEYS.md +0 -215
  19. package/script/Deploy.s.sol +0 -124
  20. package/script/DeployPeriphery.s.sol +0 -354
  21. package/slither-ci.config.json +0 -10
  22. package/test/AuditFixes.t.sol +0 -808
  23. package/test/ComprehensiveInvariant.t.sol +0 -306
  24. package/test/CoreExploitTests.t.sol +0 -2741
  25. package/test/EconomicSimulation.t.sol +0 -348
  26. package/test/EntryPointPermutations.t.sol +0 -684
  27. package/test/FlashLoanAttacks.t.sol +0 -797
  28. package/test/PermissionEscalation.t.sol +0 -711
  29. package/test/PermissionsInvariant.t.sol +0 -403
  30. package/test/RulesetTransitions.t.sol +0 -713
  31. package/test/SplitLoopTests.t.sol +0 -752
  32. package/test/TestAccessToFunds.sol +0 -2683
  33. package/test/TestAuditResponseDesignProofs.sol +0 -434
  34. package/test/TestCashOut.sol +0 -198
  35. package/test/TestCashOutCountFor.sol +0 -271
  36. package/test/TestCashOutHooks.sol +0 -351
  37. package/test/TestCashOutTimingEdge.sol +0 -241
  38. package/test/TestDataHookFuzzing.sol +0 -524
  39. package/test/TestDurationUnderflow.sol +0 -233
  40. package/test/TestFeeFreeCashOutBypass.sol +0 -949
  41. package/test/TestFeeProcessingFailure.sol +0 -218
  42. package/test/TestFees.sol +0 -619
  43. package/test/TestForwardedTokenConsumption.sol +0 -425
  44. package/test/TestInterfaceSupport.sol +0 -81
  45. package/test/TestJBERC20Inheritance.sol +0 -103
  46. package/test/TestL2SequencerPriceFeed.sol +0 -292
  47. package/test/TestLaunchProject.sol +0 -188
  48. package/test/TestMetaTx.sol +0 -217
  49. package/test/TestMetadataOffsetOverflow.sol +0 -179
  50. package/test/TestMetadataParserLib.sol +0 -471
  51. package/test/TestMigrationHeldFees.sol +0 -255
  52. package/test/TestMintTokensOf.sol +0 -185
  53. package/test/TestMultiTerminalSurplus.sol +0 -348
  54. package/test/TestMultiTokenSurplus.sol +0 -202
  55. package/test/TestMultipleAccessLimits.sol +0 -664
  56. package/test/TestPayBurnRedeemFlow.sol +0 -195
  57. package/test/TestPayHooks.sol +0 -209
  58. package/test/TestPermissions.sol +0 -324
  59. package/test/TestPermissionsEdge.sol +0 -290
  60. package/test/TestPermit2DataHook.t.sol +0 -360
  61. package/test/TestPermit2Terminal.sol +0 -372
  62. package/test/TestRulesetQueueing.sol +0 -1025
  63. package/test/TestRulesetQueuingStress.sol +0 -806
  64. package/test/TestRulesetWeightCaching.sol +0 -178
  65. package/test/TestSplits.sol +0 -391
  66. package/test/TestTerminalMigration.sol +0 -274
  67. package/test/TestTerminalPreviewParity.sol +0 -208
  68. package/test/TestTokenFlow.sol +0 -191
  69. package/test/TestWeightCacheStaleAfterRejection.sol +0 -303
  70. package/test/WeirdTokenTests.t.sol +0 -817
  71. package/test/audit/CashOutReenterPay.t.sol +0 -501
  72. package/test/audit/CodexHeldFeeRounding.t.sol +0 -159
  73. package/test/audit/CodexMigrationFeeFailure.t.sol +0 -163
  74. package/test/audit/CrossTerminalSurplusSpoof.t.sol +0 -140
  75. package/test/audit/CycledSurplusAllowanceReset.t.sol +0 -184
  76. package/test/audit/FeeFreeSurplusLifecycle.t.sol +0 -399
  77. package/test/audit/FeeFreeSurplusStale.t.sol +0 -248
  78. package/test/audit/USDTVoidReturnCompat.t.sol +0 -525
  79. package/test/fork/TestChainlinkPriceFeedFork.sol +0 -254
  80. package/test/fork/TestSequencerPriceFeedFork.sol +0 -168
  81. package/test/fork/TestTerminalPreviewParityFork.sol +0 -108
  82. package/test/formal/BondingCurveProperties.t.sol +0 -420
  83. package/test/formal/FeeProperties.t.sol +0 -252
  84. package/test/invariants/Phase3DeepInvariant.t.sol +0 -412
  85. package/test/invariants/RulesetsInvariant.t.sol +0 -125
  86. package/test/invariants/TerminalStoreInvariant.t.sol +0 -227
  87. package/test/invariants/TokensInvariant.t.sol +0 -195
  88. package/test/invariants/handlers/ComprehensiveHandler.sol +0 -303
  89. package/test/invariants/handlers/EconomicHandler.sol +0 -377
  90. package/test/invariants/handlers/Phase3Handler.sol +0 -443
  91. package/test/invariants/handlers/RulesetsHandler.sol +0 -115
  92. package/test/invariants/handlers/TerminalStoreHandler.sol +0 -151
  93. package/test/invariants/handlers/TokensHandler.sol +0 -126
  94. package/test/regression/HoldFeesCashOutReserved.t.sol +0 -415
  95. package/test/regression/WeightCacheBoundary.t.sol +0 -291
  96. package/test/trees/JBController/burnTokensOf.tree +0 -9
  97. package/test/trees/JBController/claimTokensFor.tree +0 -5
  98. package/test/trees/JBController/deployERC20For.tree +0 -5
  99. package/test/trees/JBController/getRulesetOf.tree +0 -5
  100. package/test/trees/JBController/launchProjectFor.tree +0 -12
  101. package/test/trees/JBController/launchRulesetsFor.tree +0 -8
  102. package/test/trees/JBController/migrateController.tree +0 -12
  103. package/test/trees/JBController/mintTokensOf.tree +0 -12
  104. package/test/trees/JBController/payReservedTokenToTerminal.tree +0 -8
  105. package/test/trees/JBController/receiveMigrationFrom.tree +0 -4
  106. package/test/trees/JBController/sendReservedTokensToSplitsOf.tree +0 -12
  107. package/test/trees/JBController/setMetadataOf.tree +0 -5
  108. package/test/trees/JBController/setSplitGroupsOf.tree +0 -5
  109. package/test/trees/JBController/setTokenFor.tree +0 -5
  110. package/test/trees/JBController/transferCreditsFrom.tree +0 -8
  111. package/test/trees/JBDirectory/primaryTerminalOf.tree +0 -8
  112. package/test/trees/JBDirectory/setControllerOf.tree +0 -11
  113. package/test/trees/JBDirectory/setPrimaryTerminalOf.tree +0 -15
  114. package/test/trees/JBDirectory/setTerminalsOf.tree +0 -11
  115. package/test/trees/JBERC20/initialize.tree +0 -7
  116. package/test/trees/JBERC20/name.tree +0 -5
  117. package/test/trees/JBERC20/nonces.tree +0 -5
  118. package/test/trees/JBERC20/symbol.tree +0 -5
  119. package/test/trees/JBFeelessAddresses/setFeelessAddress.tree +0 -5
  120. package/test/trees/JBFeelessAddresses/supportsInterface.tree +0 -5
  121. package/test/trees/JBFundAccessLimits/payoutLimitOf.tree +0 -5
  122. package/test/trees/JBFundAccessLimits/payoutLimitsOf.tree +0 -8
  123. package/test/trees/JBFundAccessLimits/setFundAccessLimitsFor.tree +0 -18
  124. package/test/trees/JBFundAccessLimits/surplusAllowanceOf.tree +0 -5
  125. package/test/trees/JBFundAccessLimits/surplusAllowancesOf.tree +0 -8
  126. package/test/trees/JBMetadataResolver/getDataFor.tree +0 -8
  127. package/test/trees/JBMultiTerminal/accountingContextsOf.tree +0 -5
  128. package/test/trees/JBMultiTerminal/addAccountingContextsFor.tree +0 -10
  129. package/test/trees/JBMultiTerminal/addToBalanceOf.tree +0 -23
  130. package/test/trees/JBMultiTerminal/cashOutTokensOf.tree +0 -23
  131. package/test/trees/JBMultiTerminal/executePayout.tree +0 -32
  132. package/test/trees/JBMultiTerminal/executeProcessFee.tree +0 -14
  133. package/test/trees/JBMultiTerminal/migrateBalanceOf.tree +0 -12
  134. package/test/trees/JBMultiTerminal/pay.tree +0 -23
  135. package/test/trees/JBMultiTerminal/processHeldFeesOf.tree +0 -8
  136. package/test/trees/JBMultiTerminal/sendPayoutsOf.tree +0 -34
  137. package/test/trees/JBMultiTerminal/useAllowanceOf.tree +0 -16
  138. package/test/trees/JBPermissions/hasPermission.tree +0 -8
  139. package/test/trees/JBPermissions/hasPermissions.tree +0 -8
  140. package/test/trees/JBPermissions/setPermissionsFor.tree +0 -5
  141. package/test/trees/JBPrices/addPriceFeedFor.tree +0 -14
  142. package/test/trees/JBPrices/pricePerUnitOf.tree +0 -11
  143. package/test/trees/JBProjects/createFor.tree +0 -11
  144. package/test/trees/JBProjects/setTokenUriResolver.tree +0 -5
  145. package/test/trees/JBProjects/supportsInterface.tree +0 -9
  146. package/test/trees/JBProjects/tokenURI.tree +0 -5
  147. package/test/trees/JBRulesets/currentApprovalStatusForLatestRulesetOf.tree +0 -8
  148. package/test/trees/JBRulesets/currentOf.tree +0 -12
  149. package/test/trees/JBRulesets/getRulesetOf.tree +0 -5
  150. package/test/trees/JBRulesets/latestQueuedRulesetOf.tree +0 -10
  151. package/test/trees/JBRulesets/rulesetsOf.tree +0 -11
  152. package/test/trees/JBRulesets/upcomingRulesetOf.tree +0 -20
  153. package/test/trees/JBRulesets/updateRulesetWeightCache.tree +0 -5
  154. package/test/trees/JBSplits/setSplitGroupsOf.tree +0 -17
  155. package/test/trees/JBSplits/splitsOf.tree +0 -5
  156. package/test/trees/JBTerminalStore/currentReclaimableSurplusOf.tree +0 -16
  157. package/test/trees/JBTerminalStore/currentSurplusOf.tree +0 -25
  158. package/test/trees/JBTerminalStore/currentTotalSurplusOf.tree +0 -5
  159. package/test/trees/JBTerminalStore/recordCashOutsFor.tree +0 -16
  160. package/test/trees/JBTerminalStore/recordPaymentFrom.tree +0 -14
  161. package/test/trees/JBTerminalStore/recordPayoutFor.tree +0 -10
  162. package/test/trees/JBTerminalStore/recordTerminalMigration.tree +0 -5
  163. package/test/trees/JBTerminalStore/recordUsedAllowanceOf.tree +0 -10
  164. package/test/trees/JBTokens/burnFrom.tree +0 -10
  165. package/test/trees/JBTokens/claimTokensFor.tree +0 -10
  166. package/test/trees/JBTokens/deployERC20For.tree +0 -12
  167. package/test/trees/JBTokens/mintFor.tree +0 -10
  168. package/test/trees/JBTokens/setTokenFor.tree +0 -11
  169. package/test/trees/JBTokens/totalBalanceOf.tree +0 -5
  170. package/test/trees/JBTokens/totalSupplyOf.tree +0 -5
  171. package/test/trees/JBTokens/transferCreditsFrom.tree +0 -8
  172. package/test/trees/mintTokensOf.tree +0 -12
  173. package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +0 -223
  174. package/test/units/static/JBController/JBControllerSetup.sol +0 -50
  175. package/test/units/static/JBController/TestBurnTokensOf.sol +0 -114
  176. package/test/units/static/JBController/TestClaimTokensFor.sol +0 -63
  177. package/test/units/static/JBController/TestDeployErc20For.sol +0 -86
  178. package/test/units/static/JBController/TestLaunchProjectFor.sol +0 -302
  179. package/test/units/static/JBController/TestLaunchRulesetsFor.sol +0 -342
  180. package/test/units/static/JBController/TestMigrateController.sol +0 -157
  181. package/test/units/static/JBController/TestMintTokensOfUnits.sol +0 -111
  182. package/test/units/static/JBController/TestOmnichainRulesetOperator.sol +0 -324
  183. package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +0 -74
  184. package/test/units/static/JBController/TestPreviewMintOf.sol +0 -117
  185. package/test/units/static/JBController/TestReceiveMigrationFrom.sol +0 -99
  186. package/test/units/static/JBController/TestRulesetViews.sol +0 -225
  187. package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +0 -615
  188. package/test/units/static/JBController/TestSetSplitGroupsOf.sol +0 -68
  189. package/test/units/static/JBController/TestSetTokenFor.sol +0 -239
  190. package/test/units/static/JBController/TestSetUriOf.sol +0 -57
  191. package/test/units/static/JBController/TestTransferCreditsFrom.sol +0 -169
  192. package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +0 -211
  193. package/test/units/static/JBDirectory/JBDirectorySetup.sol +0 -26
  194. package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +0 -126
  195. package/test/units/static/JBDirectory/TestSetControllerOf.sol +0 -183
  196. package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +0 -104
  197. package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +0 -179
  198. package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +0 -137
  199. package/test/units/static/JBERC20/JBERC20Setup.sol +0 -34
  200. package/test/units/static/JBERC20/SigUtils.sol +0 -36
  201. package/test/units/static/JBERC20/TestInitialize.sol +0 -60
  202. package/test/units/static/JBERC20/TestName.sol +0 -30
  203. package/test/units/static/JBERC20/TestNonces.sol +0 -62
  204. package/test/units/static/JBERC20/TestSymbol.sol +0 -31
  205. package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +0 -22
  206. package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +0 -30
  207. package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +0 -35
  208. package/test/units/static/JBFees/TestFeesFuzz.sol +0 -79
  209. package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +0 -16
  210. package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +0 -71
  211. package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +0 -24
  212. package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +0 -163
  213. package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +0 -59
  214. package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +0 -101
  215. package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +0 -189
  216. package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +0 -64
  217. package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +0 -102
  218. package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +0 -90
  219. package/test/units/static/JBMetadataResolver/TestMetadataResolverEdgeCases.sol +0 -247
  220. package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +0 -229
  221. package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +0 -50
  222. package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +0 -72
  223. package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +0 -289
  224. package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +0 -474
  225. package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +0 -624
  226. package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +0 -578
  227. package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +0 -202
  228. package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +0 -222
  229. package/test/units/static/JBMultiTerminal/TestPay.sol +0 -604
  230. package/test/units/static/JBMultiTerminal/TestPreviewCashOutFrom.sol +0 -117
  231. package/test/units/static/JBMultiTerminal/TestPreviewPayFor.sol +0 -114
  232. package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +0 -228
  233. package/test/units/static/JBMultiTerminal/TestSelfPayRevert.sol +0 -55
  234. package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +0 -257
  235. package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +0 -611
  236. package/test/units/static/JBPermissions/JBPermissionsSetup.sol +0 -20
  237. package/test/units/static/JBPermissions/TestHasPermission.sol +0 -50
  238. package/test/units/static/JBPermissions/TestHasPermissions.sol +0 -93
  239. package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +0 -64
  240. package/test/units/static/JBPrices/JBPricesSetup.sol +0 -32
  241. package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +0 -107
  242. package/test/units/static/JBPrices/TestPricePerUnitOf.sol +0 -132
  243. package/test/units/static/JBPrices/TestPrices.sol +0 -265
  244. package/test/units/static/JBProjects/JBProjectsSetup.sol +0 -22
  245. package/test/units/static/JBProjects/TestCreateFor.sol +0 -71
  246. package/test/units/static/JBProjects/TestInitialProject.sol +0 -21
  247. package/test/units/static/JBProjects/TestInterfaces.sol +0 -26
  248. package/test/units/static/JBProjects/TestSetResolver.sol +0 -37
  249. package/test/units/static/JBProjects/TestTokenUri.sol +0 -40
  250. package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +0 -108
  251. package/test/units/static/JBRulesets/JBRulesetsSetup.sol +0 -24
  252. package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +0 -265
  253. package/test/units/static/JBRulesets/TestCurrentOf.sol +0 -242
  254. package/test/units/static/JBRulesets/TestGetRulesetOf.sol +0 -100
  255. package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +0 -260
  256. package/test/units/static/JBRulesets/TestRulesets.sol +0 -632
  257. package/test/units/static/JBRulesets/TestRulesetsOf.sol +0 -37
  258. package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +0 -522
  259. package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +0 -96
  260. package/test/units/static/JBSplits/JBSplitsSetup.sol +0 -26
  261. package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +0 -552
  262. package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +0 -377
  263. package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +0 -267
  264. package/test/units/static/JBSplits/TestSplitsOf.sol +0 -24
  265. package/test/units/static/JBSplits/TestSplitsPacking.sol +0 -36
  266. package/test/units/static/JBSurplus/TestSurplusFuzz.sol +0 -160
  267. package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +0 -45
  268. package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +0 -536
  269. package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +0 -463
  270. package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +0 -135
  271. package/test/units/static/JBTerminalStore/TestPreviewCashOutFrom.sol +0 -476
  272. package/test/units/static/JBTerminalStore/TestPreviewPayFrom.sol +0 -494
  273. package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +0 -652
  274. package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +0 -744
  275. package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +0 -289
  276. package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +0 -138
  277. package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +0 -415
  278. package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +0 -219
  279. package/test/units/static/JBTokens/JBTokensSetup.sol +0 -32
  280. package/test/units/static/JBTokens/TestBurnFrom.sol +0 -107
  281. package/test/units/static/JBTokens/TestClaimTokensFor.sol +0 -110
  282. package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +0 -92
  283. package/test/units/static/JBTokens/TestMintFor.sol +0 -100
  284. package/test/units/static/JBTokens/TestSetTokenFor.sol +0 -98
  285. package/test/units/static/JBTokens/TestTotalBalanceOf.sol +0 -65
  286. package/test/units/static/JBTokens/TestTotalSupplyOf.sol +0 -56
  287. package/test/units/static/JBTokens/TestTransferCreditsFrom.sol +0 -56
@@ -1,403 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity ^0.8.6;
3
-
4
- import {Test} from "forge-std/Test.sol";
5
- import {CommonBase} from "forge-std/Base.sol";
6
- import {StdCheats} from "forge-std/StdCheats.sol";
7
- import {StdUtils} from "forge-std/StdUtils.sol";
8
-
9
- import {JBPermissions} from "../src/JBPermissions.sol";
10
- import {IJBPermissions} from "../src/interfaces/IJBPermissions.sol";
11
- import {JBPermissionsData} from "../src/structs/JBPermissionsData.sol";
12
-
13
- /// @title PermissionsHandler
14
- /// @notice Stateful handler for JBPermissions invariant testing.
15
- /// Randomly sets, revokes, and checks permissions while tracking expected state.
16
- contract PermissionsHandler is CommonBase, StdCheats, StdUtils {
17
- JBPermissions public immutable PERMISSIONS;
18
-
19
- address[] public accounts;
20
- address[] public operators;
21
- uint56[] public projectIds;
22
-
23
- // Ghost state: track what we've set.
24
- // Keyed by keccak256(operator, account, projectId).
25
- mapping(bytes32 => uint256) public expectedPacked;
26
-
27
- // Counters.
28
- uint256 public setCount;
29
- uint256 public revokeCount;
30
- uint256 public rootSetCount;
31
- uint256 public rootForwardAttempts;
32
- uint256 public rootForwardBlocked;
33
- uint256 public wildcardSetAttempts;
34
- uint256 public wildcardSetBlocked;
35
-
36
- constructor() {
37
- PERMISSIONS = new JBPermissions(address(0));
38
-
39
- accounts.push(makeAddr("accountA"));
40
- accounts.push(makeAddr("accountB"));
41
- accounts.push(makeAddr("accountC"));
42
-
43
- operators.push(makeAddr("operatorX"));
44
- operators.push(makeAddr("operatorY"));
45
- operators.push(makeAddr("operatorZ"));
46
-
47
- projectIds.push(1);
48
- projectIds.push(2);
49
- projectIds.push(3);
50
- }
51
-
52
- /// @notice Set random permissions for a random (operator, account, projectId) triple.
53
- function setPermissions(
54
- uint256 accountSeed,
55
- uint256 operatorSeed,
56
- uint256 projectSeed,
57
- uint8[] memory permissionIds
58
- )
59
- public
60
- {
61
- address account = accounts[bound(accountSeed, 0, accounts.length - 1)];
62
- address operator = operators[bound(operatorSeed, 0, operators.length - 1)];
63
- uint56 projectId = projectIds[bound(projectSeed, 0, projectIds.length - 1)];
64
-
65
- // Filter out permission ID 0 (invalid) and truncate long arrays.
66
- if (permissionIds.length > 10) {
67
- assembly {
68
- mstore(permissionIds, 10)
69
- }
70
- }
71
-
72
- uint8[] memory validIds = new uint8[](permissionIds.length);
73
- uint256 validCount;
74
- for (uint256 i; i < permissionIds.length; i++) {
75
- if (permissionIds[i] > 0) {
76
- validIds[validCount] = permissionIds[i];
77
- validCount++;
78
- }
79
- }
80
-
81
- // Resize to valid count.
82
- uint8[] memory finalIds = new uint8[](validCount);
83
- for (uint256 i; i < validCount; i++) {
84
- finalIds[i] = validIds[i];
85
- }
86
-
87
- // Track expected state.
88
- bytes32 key = keccak256(abi.encodePacked(operator, account, projectId));
89
- uint256 packed;
90
- for (uint256 i; i < validCount; i++) {
91
- packed |= uint256(1) << finalIds[i];
92
- }
93
- expectedPacked[key] = packed;
94
-
95
- // Account sets permissions for itself.
96
- vm.prank(account);
97
- PERMISSIONS.setPermissionsFor(
98
- account, JBPermissionsData({operator: operator, projectId: projectId, permissionIds: finalIds})
99
- );
100
-
101
- setCount++;
102
-
103
- // Track ROOT sets.
104
- for (uint256 i; i < validCount; i++) {
105
- if (finalIds[i] == 1) {
106
- rootSetCount++;
107
- break;
108
- }
109
- }
110
- }
111
-
112
- /// @notice Revoke permissions by setting empty array.
113
- function revokePermissions(uint256 accountSeed, uint256 operatorSeed, uint256 projectSeed) public {
114
- address account = accounts[bound(accountSeed, 0, accounts.length - 1)];
115
- address operator = operators[bound(operatorSeed, 0, operators.length - 1)];
116
- uint56 projectId = projectIds[bound(projectSeed, 0, projectIds.length - 1)];
117
-
118
- bytes32 key = keccak256(abi.encodePacked(operator, account, projectId));
119
- expectedPacked[key] = 0;
120
-
121
- uint8[] memory emptyIds = new uint8[](0);
122
-
123
- vm.prank(account);
124
- PERMISSIONS.setPermissionsFor(
125
- account, JBPermissionsData({operator: operator, projectId: projectId, permissionIds: emptyIds})
126
- );
127
-
128
- revokeCount++;
129
- }
130
-
131
- /// @notice Attempt ROOT forwarding (should always be blocked).
132
- function attemptRootForwarding(uint256 accountSeed, uint256 projectSeed) public {
133
- address account = accounts[bound(accountSeed, 0, accounts.length - 1)];
134
- address operator = operators[0]; // operatorX
135
- address thirdParty = operators[1]; // operatorY
136
- uint56 projectId = projectIds[bound(projectSeed, 0, projectIds.length - 1)];
137
-
138
- rootForwardAttempts++;
139
-
140
- // First give operator ROOT.
141
- uint8[] memory rootPerms = new uint8[](1);
142
- rootPerms[0] = 1; // ROOT
143
-
144
- vm.prank(account);
145
- PERMISSIONS.setPermissionsFor(
146
- account, JBPermissionsData({operator: operator, projectId: projectId, permissionIds: rootPerms})
147
- );
148
-
149
- // Update ghost state.
150
- bytes32 rootKey = keccak256(abi.encodePacked(operator, account, projectId));
151
- expectedPacked[rootKey] = uint256(1) << 1;
152
-
153
- // Now operator tries to forward ROOT to thirdParty.
154
- vm.prank(operator);
155
- try PERMISSIONS.setPermissionsFor(
156
- account, JBPermissionsData({operator: thirdParty, projectId: projectId, permissionIds: rootPerms})
157
- ) {
158
- // Should not reach here.
159
- }
160
- catch {
161
- rootForwardBlocked++;
162
- }
163
- }
164
-
165
- /// @notice Attempt wildcard permission setting by operator (should be blocked).
166
- function attemptWildcardByOperator(uint256 accountSeed, uint256 projectSeed) public {
167
- address account = accounts[bound(accountSeed, 0, accounts.length - 1)];
168
- address operator = operators[0];
169
- address thirdParty = operators[1];
170
- uint56 projectId = projectIds[bound(projectSeed, 0, projectIds.length - 1)];
171
-
172
- wildcardSetAttempts++;
173
-
174
- // Give operator ROOT on a specific project.
175
- uint8[] memory rootPerms = new uint8[](1);
176
- rootPerms[0] = 1;
177
-
178
- vm.prank(account);
179
- PERMISSIONS.setPermissionsFor(
180
- account, JBPermissionsData({operator: operator, projectId: projectId, permissionIds: rootPerms})
181
- );
182
-
183
- bytes32 rootKey = keccak256(abi.encodePacked(operator, account, projectId));
184
- expectedPacked[rootKey] = uint256(1) << 1;
185
-
186
- // Operator tries to set permission on wildcard project (0).
187
- uint8[] memory somePerms = new uint8[](1);
188
- somePerms[0] = 5;
189
-
190
- vm.prank(operator);
191
- try PERMISSIONS.setPermissionsFor(
192
- account, JBPermissionsData({operator: thirdParty, projectId: 0, permissionIds: somePerms})
193
- ) {
194
- // Should not reach here.
195
- }
196
- catch {
197
- wildcardSetBlocked++;
198
- }
199
- }
200
-
201
- /// @notice Get the expected packed permissions for a triple.
202
- function getExpected(address operator, address account, uint56 projectId) external view returns (uint256) {
203
- bytes32 key = keccak256(abi.encodePacked(operator, account, projectId));
204
- return expectedPacked[key];
205
- }
206
- }
207
-
208
- /// @title PermissionsInvariantTest
209
- /// @notice Stateful invariant tests proving JBPermissions maintains consistency
210
- /// through random set/revoke cycles.
211
- contract PermissionsInvariantTest is Test {
212
- PermissionsHandler handler;
213
-
214
- function setUp() public {
215
- handler = new PermissionsHandler();
216
- targetContract(address(handler));
217
- }
218
-
219
- /// @notice Packed permissions in storage always match what was last set.
220
- function invariant_packedMatchesExpected() public view {
221
- JBPermissions perms = handler.PERMISSIONS();
222
-
223
- // Check all (operator, account, projectId) combinations.
224
- for (uint256 o; o < 3; o++) {
225
- for (uint256 a; a < 3; a++) {
226
- for (uint256 p; p < 3; p++) {
227
- address operator = handler.operators(o);
228
- address account = handler.accounts(a);
229
- uint56 projectId = handler.projectIds(p);
230
-
231
- uint256 expected = handler.getExpected(operator, account, projectId);
232
- uint256 actual = perms.permissionsOf(operator, account, projectId);
233
-
234
- assertEq(actual, expected, "Packed permissions mismatch");
235
- }
236
- }
237
- }
238
- }
239
-
240
- /// @notice Bit 0 is never set in any stored permissions.
241
- function invariant_bit0NeverSet() public view {
242
- JBPermissions perms = handler.PERMISSIONS();
243
-
244
- for (uint256 o; o < 3; o++) {
245
- for (uint256 a; a < 3; a++) {
246
- for (uint256 p; p < 3; p++) {
247
- uint256 packed =
248
- perms.permissionsOf(handler.operators(o), handler.accounts(a), handler.projectIds(p));
249
- assertFalse((packed & 1) == 1, "Bit 0 should never be set");
250
- }
251
- }
252
- }
253
- }
254
-
255
- /// @notice ROOT forwarding is always blocked.
256
- function invariant_rootForwardingAlwaysBlocked() public view {
257
- if (handler.rootForwardAttempts() > 0) {
258
- assertEq(
259
- handler.rootForwardBlocked(),
260
- handler.rootForwardAttempts(),
261
- "All ROOT forwarding attempts must be blocked"
262
- );
263
- }
264
- }
265
-
266
- /// @notice Wildcard permission setting by operators is always blocked.
267
- function invariant_wildcardByOperatorAlwaysBlocked() public view {
268
- if (handler.wildcardSetAttempts() > 0) {
269
- assertEq(
270
- handler.wildcardSetBlocked(),
271
- handler.wildcardSetAttempts(),
272
- "All wildcard-by-operator attempts must be blocked"
273
- );
274
- }
275
- }
276
-
277
- /// @notice hasPermission returns true iff the bit is set (no false positives/negatives).
278
- function invariant_hasPermissionMatchesBits() public view {
279
- JBPermissions perms = handler.PERMISSIONS();
280
-
281
- // Spot-check a few permission IDs across all triples.
282
- uint256[5] memory checkIds = [uint256(1), 2, 5, 42, 255];
283
-
284
- for (uint256 o; o < 3; o++) {
285
- for (uint256 a; a < 3; a++) {
286
- for (uint256 p; p < 3; p++) {
287
- address operator = handler.operators(o);
288
- address account = handler.accounts(a);
289
- uint56 projectId = handler.projectIds(p);
290
-
291
- uint256 packed = perms.permissionsOf(operator, account, projectId);
292
-
293
- for (uint256 c; c < checkIds.length; c++) {
294
- bool expected = ((packed >> checkIds[c]) & 1) == 1;
295
- bool actual = perms.hasPermission(operator, account, projectId, checkIds[c], false, false);
296
- assertEq(actual, expected, "hasPermission must match bit state");
297
- }
298
- }
299
- }
300
- }
301
- }
302
- }
303
-
304
- /// @title PermissionsBitPackingTest
305
- /// @notice Formal property tests for JBPermissions bit-packing roundtrip
306
- /// and hasPermissions batch logic.
307
- contract PermissionsBitPackingTest is Test {
308
- JBPermissions perms;
309
-
310
- address account = makeAddr("account");
311
- address operator = makeAddr("operator");
312
- uint56 projectId = 7;
313
-
314
- function setUp() public {
315
- perms = new JBPermissions(address(0));
316
- }
317
-
318
- /// @notice hasPermissions with an empty array returns true (vacuous truth).
319
- function test_hasPermissions_emptyArray_returnsTrue() public view {
320
- uint256[] memory empty = new uint256[](0);
321
- bool result = perms.hasPermissions(operator, account, projectId, empty, false, false);
322
- assertTrue(result, "Empty permission array should return true (vacuous truth)");
323
- }
324
-
325
- /// @notice Fuzz: set N permissions, verify each bit is set and all others are not.
326
- function testFuzz_bitPackingRoundtrip(uint8 id1, uint8 id2, uint8 id3) public {
327
- // Bound to valid range (1-255).
328
- id1 = uint8(bound(uint256(id1), 1, 255));
329
- id2 = uint8(bound(uint256(id2), 1, 255));
330
- id3 = uint8(bound(uint256(id3), 1, 255));
331
-
332
- uint8[] memory ids = new uint8[](3);
333
- ids[0] = id1;
334
- ids[1] = id2;
335
- ids[2] = id3;
336
-
337
- vm.prank(account);
338
- perms.setPermissionsFor(
339
- account, JBPermissionsData({operator: operator, projectId: projectId, permissionIds: ids})
340
- );
341
-
342
- // Each set ID should return true.
343
- assertTrue(perms.hasPermission(operator, account, projectId, id1, false, false), "id1 should be set");
344
- assertTrue(perms.hasPermission(operator, account, projectId, id2, false, false), "id2 should be set");
345
- assertTrue(perms.hasPermission(operator, account, projectId, id3, false, false), "id3 should be set");
346
-
347
- // Verify the packed value has exactly the right bits.
348
- uint256 packed = perms.permissionsOf(operator, account, projectId);
349
- uint256 expectedPacked = (uint256(1) << id1) | (uint256(1) << id2) | (uint256(1) << id3);
350
- assertEq(packed, expectedPacked, "Packed value should exactly match OR of set bits");
351
-
352
- // Bit 0 must not be set.
353
- assertFalse((packed & 1) == 1, "Bit 0 must never be set");
354
- }
355
-
356
- /// @notice hasPermissions batch check: all permissions must be present.
357
- function test_hasPermissions_batch_allRequired() public {
358
- uint8[] memory ids = new uint8[](3);
359
- ids[0] = 5;
360
- ids[1] = 10;
361
- ids[2] = 200;
362
-
363
- vm.prank(account);
364
- perms.setPermissionsFor(
365
- account, JBPermissionsData({operator: operator, projectId: projectId, permissionIds: ids})
366
- );
367
-
368
- // All three set -> true.
369
- uint256[] memory check3 = new uint256[](3);
370
- check3[0] = 5;
371
- check3[1] = 10;
372
- check3[2] = 200;
373
- assertTrue(perms.hasPermissions(operator, account, projectId, check3, false, false), "All three should pass");
374
-
375
- // Missing one (15 not set) -> false.
376
- uint256[] memory check4 = new uint256[](4);
377
- check4[0] = 5;
378
- check4[1] = 10;
379
- check4[2] = 200;
380
- check4[3] = 15;
381
- assertFalse(
382
- perms.hasPermissions(operator, account, projectId, check4, false, false),
383
- "Missing permission 15 should fail batch check"
384
- );
385
- }
386
-
387
- /// @notice Event emission includes correct packed value.
388
- function test_eventEmission_packedValue() public {
389
- uint8[] memory ids = new uint8[](2);
390
- ids[0] = 3;
391
- ids[1] = 7;
392
-
393
- uint256 expectedPacked = (uint256(1) << 3) | (uint256(1) << 7);
394
-
395
- vm.expectEmit(true, true, true, true);
396
- emit IJBPermissions.OperatorPermissionsSet(operator, account, projectId, ids, expectedPacked, account);
397
-
398
- vm.prank(account);
399
- perms.setPermissionsFor(
400
- account, JBPermissionsData({operator: operator, projectId: projectId, permissionIds: ids})
401
- );
402
- }
403
- }