@bananapus/core-v6 0.0.36 → 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 (286) 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 +26 -5
  5. package/src/JBMultiTerminal.sol +85 -47
  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/CrossTerminalSurplusSpoof.t.sol +0 -140
  74. package/test/audit/CycledSurplusAllowanceReset.t.sol +0 -184
  75. package/test/audit/FeeFreeSurplusLifecycle.t.sol +0 -399
  76. package/test/audit/FeeFreeSurplusStale.t.sol +0 -248
  77. package/test/audit/USDTVoidReturnCompat.t.sol +0 -525
  78. package/test/fork/TestChainlinkPriceFeedFork.sol +0 -254
  79. package/test/fork/TestSequencerPriceFeedFork.sol +0 -168
  80. package/test/fork/TestTerminalPreviewParityFork.sol +0 -108
  81. package/test/formal/BondingCurveProperties.t.sol +0 -420
  82. package/test/formal/FeeProperties.t.sol +0 -252
  83. package/test/invariants/Phase3DeepInvariant.t.sol +0 -412
  84. package/test/invariants/RulesetsInvariant.t.sol +0 -125
  85. package/test/invariants/TerminalStoreInvariant.t.sol +0 -227
  86. package/test/invariants/TokensInvariant.t.sol +0 -195
  87. package/test/invariants/handlers/ComprehensiveHandler.sol +0 -303
  88. package/test/invariants/handlers/EconomicHandler.sol +0 -377
  89. package/test/invariants/handlers/Phase3Handler.sol +0 -443
  90. package/test/invariants/handlers/RulesetsHandler.sol +0 -115
  91. package/test/invariants/handlers/TerminalStoreHandler.sol +0 -151
  92. package/test/invariants/handlers/TokensHandler.sol +0 -126
  93. package/test/regression/HoldFeesCashOutReserved.t.sol +0 -415
  94. package/test/regression/WeightCacheBoundary.t.sol +0 -291
  95. package/test/trees/JBController/burnTokensOf.tree +0 -9
  96. package/test/trees/JBController/claimTokensFor.tree +0 -5
  97. package/test/trees/JBController/deployERC20For.tree +0 -5
  98. package/test/trees/JBController/getRulesetOf.tree +0 -5
  99. package/test/trees/JBController/launchProjectFor.tree +0 -12
  100. package/test/trees/JBController/launchRulesetsFor.tree +0 -8
  101. package/test/trees/JBController/migrateController.tree +0 -12
  102. package/test/trees/JBController/mintTokensOf.tree +0 -12
  103. package/test/trees/JBController/payReservedTokenToTerminal.tree +0 -8
  104. package/test/trees/JBController/receiveMigrationFrom.tree +0 -4
  105. package/test/trees/JBController/sendReservedTokensToSplitsOf.tree +0 -12
  106. package/test/trees/JBController/setMetadataOf.tree +0 -5
  107. package/test/trees/JBController/setSplitGroupsOf.tree +0 -5
  108. package/test/trees/JBController/setTokenFor.tree +0 -5
  109. package/test/trees/JBController/transferCreditsFrom.tree +0 -8
  110. package/test/trees/JBDirectory/primaryTerminalOf.tree +0 -8
  111. package/test/trees/JBDirectory/setControllerOf.tree +0 -11
  112. package/test/trees/JBDirectory/setPrimaryTerminalOf.tree +0 -15
  113. package/test/trees/JBDirectory/setTerminalsOf.tree +0 -11
  114. package/test/trees/JBERC20/initialize.tree +0 -7
  115. package/test/trees/JBERC20/name.tree +0 -5
  116. package/test/trees/JBERC20/nonces.tree +0 -5
  117. package/test/trees/JBERC20/symbol.tree +0 -5
  118. package/test/trees/JBFeelessAddresses/setFeelessAddress.tree +0 -5
  119. package/test/trees/JBFeelessAddresses/supportsInterface.tree +0 -5
  120. package/test/trees/JBFundAccessLimits/payoutLimitOf.tree +0 -5
  121. package/test/trees/JBFundAccessLimits/payoutLimitsOf.tree +0 -8
  122. package/test/trees/JBFundAccessLimits/setFundAccessLimitsFor.tree +0 -18
  123. package/test/trees/JBFundAccessLimits/surplusAllowanceOf.tree +0 -5
  124. package/test/trees/JBFundAccessLimits/surplusAllowancesOf.tree +0 -8
  125. package/test/trees/JBMetadataResolver/getDataFor.tree +0 -8
  126. package/test/trees/JBMultiTerminal/accountingContextsOf.tree +0 -5
  127. package/test/trees/JBMultiTerminal/addAccountingContextsFor.tree +0 -10
  128. package/test/trees/JBMultiTerminal/addToBalanceOf.tree +0 -23
  129. package/test/trees/JBMultiTerminal/cashOutTokensOf.tree +0 -23
  130. package/test/trees/JBMultiTerminal/executePayout.tree +0 -32
  131. package/test/trees/JBMultiTerminal/executeProcessFee.tree +0 -14
  132. package/test/trees/JBMultiTerminal/migrateBalanceOf.tree +0 -12
  133. package/test/trees/JBMultiTerminal/pay.tree +0 -23
  134. package/test/trees/JBMultiTerminal/processHeldFeesOf.tree +0 -8
  135. package/test/trees/JBMultiTerminal/sendPayoutsOf.tree +0 -34
  136. package/test/trees/JBMultiTerminal/useAllowanceOf.tree +0 -16
  137. package/test/trees/JBPermissions/hasPermission.tree +0 -8
  138. package/test/trees/JBPermissions/hasPermissions.tree +0 -8
  139. package/test/trees/JBPermissions/setPermissionsFor.tree +0 -5
  140. package/test/trees/JBPrices/addPriceFeedFor.tree +0 -14
  141. package/test/trees/JBPrices/pricePerUnitOf.tree +0 -11
  142. package/test/trees/JBProjects/createFor.tree +0 -11
  143. package/test/trees/JBProjects/setTokenUriResolver.tree +0 -5
  144. package/test/trees/JBProjects/supportsInterface.tree +0 -9
  145. package/test/trees/JBProjects/tokenURI.tree +0 -5
  146. package/test/trees/JBRulesets/currentApprovalStatusForLatestRulesetOf.tree +0 -8
  147. package/test/trees/JBRulesets/currentOf.tree +0 -12
  148. package/test/trees/JBRulesets/getRulesetOf.tree +0 -5
  149. package/test/trees/JBRulesets/latestQueuedRulesetOf.tree +0 -10
  150. package/test/trees/JBRulesets/rulesetsOf.tree +0 -11
  151. package/test/trees/JBRulesets/upcomingRulesetOf.tree +0 -20
  152. package/test/trees/JBRulesets/updateRulesetWeightCache.tree +0 -5
  153. package/test/trees/JBSplits/setSplitGroupsOf.tree +0 -17
  154. package/test/trees/JBSplits/splitsOf.tree +0 -5
  155. package/test/trees/JBTerminalStore/currentReclaimableSurplusOf.tree +0 -16
  156. package/test/trees/JBTerminalStore/currentSurplusOf.tree +0 -25
  157. package/test/trees/JBTerminalStore/currentTotalSurplusOf.tree +0 -5
  158. package/test/trees/JBTerminalStore/recordCashOutsFor.tree +0 -16
  159. package/test/trees/JBTerminalStore/recordPaymentFrom.tree +0 -14
  160. package/test/trees/JBTerminalStore/recordPayoutFor.tree +0 -10
  161. package/test/trees/JBTerminalStore/recordTerminalMigration.tree +0 -5
  162. package/test/trees/JBTerminalStore/recordUsedAllowanceOf.tree +0 -10
  163. package/test/trees/JBTokens/burnFrom.tree +0 -10
  164. package/test/trees/JBTokens/claimTokensFor.tree +0 -10
  165. package/test/trees/JBTokens/deployERC20For.tree +0 -12
  166. package/test/trees/JBTokens/mintFor.tree +0 -10
  167. package/test/trees/JBTokens/setTokenFor.tree +0 -11
  168. package/test/trees/JBTokens/totalBalanceOf.tree +0 -5
  169. package/test/trees/JBTokens/totalSupplyOf.tree +0 -5
  170. package/test/trees/JBTokens/transferCreditsFrom.tree +0 -8
  171. package/test/trees/mintTokensOf.tree +0 -12
  172. package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +0 -223
  173. package/test/units/static/JBController/JBControllerSetup.sol +0 -50
  174. package/test/units/static/JBController/TestBurnTokensOf.sol +0 -114
  175. package/test/units/static/JBController/TestClaimTokensFor.sol +0 -63
  176. package/test/units/static/JBController/TestDeployErc20For.sol +0 -86
  177. package/test/units/static/JBController/TestLaunchProjectFor.sol +0 -302
  178. package/test/units/static/JBController/TestLaunchRulesetsFor.sol +0 -342
  179. package/test/units/static/JBController/TestMigrateController.sol +0 -157
  180. package/test/units/static/JBController/TestMintTokensOfUnits.sol +0 -111
  181. package/test/units/static/JBController/TestOmnichainRulesetOperator.sol +0 -324
  182. package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +0 -74
  183. package/test/units/static/JBController/TestPreviewMintOf.sol +0 -117
  184. package/test/units/static/JBController/TestReceiveMigrationFrom.sol +0 -99
  185. package/test/units/static/JBController/TestRulesetViews.sol +0 -225
  186. package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +0 -615
  187. package/test/units/static/JBController/TestSetSplitGroupsOf.sol +0 -68
  188. package/test/units/static/JBController/TestSetTokenFor.sol +0 -239
  189. package/test/units/static/JBController/TestSetUriOf.sol +0 -57
  190. package/test/units/static/JBController/TestTransferCreditsFrom.sol +0 -169
  191. package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +0 -211
  192. package/test/units/static/JBDirectory/JBDirectorySetup.sol +0 -26
  193. package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +0 -126
  194. package/test/units/static/JBDirectory/TestSetControllerOf.sol +0 -183
  195. package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +0 -104
  196. package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +0 -179
  197. package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +0 -137
  198. package/test/units/static/JBERC20/JBERC20Setup.sol +0 -34
  199. package/test/units/static/JBERC20/SigUtils.sol +0 -36
  200. package/test/units/static/JBERC20/TestInitialize.sol +0 -60
  201. package/test/units/static/JBERC20/TestName.sol +0 -30
  202. package/test/units/static/JBERC20/TestNonces.sol +0 -62
  203. package/test/units/static/JBERC20/TestSymbol.sol +0 -31
  204. package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +0 -22
  205. package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +0 -30
  206. package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +0 -35
  207. package/test/units/static/JBFees/TestFeesFuzz.sol +0 -79
  208. package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +0 -16
  209. package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +0 -71
  210. package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +0 -24
  211. package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +0 -163
  212. package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +0 -59
  213. package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +0 -101
  214. package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +0 -189
  215. package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +0 -64
  216. package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +0 -102
  217. package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +0 -90
  218. package/test/units/static/JBMetadataResolver/TestMetadataResolverEdgeCases.sol +0 -247
  219. package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +0 -229
  220. package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +0 -50
  221. package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +0 -72
  222. package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +0 -289
  223. package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +0 -474
  224. package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +0 -624
  225. package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +0 -578
  226. package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +0 -202
  227. package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +0 -222
  228. package/test/units/static/JBMultiTerminal/TestPay.sol +0 -604
  229. package/test/units/static/JBMultiTerminal/TestPreviewCashOutFrom.sol +0 -117
  230. package/test/units/static/JBMultiTerminal/TestPreviewPayFor.sol +0 -114
  231. package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +0 -228
  232. package/test/units/static/JBMultiTerminal/TestSelfPayRevert.sol +0 -55
  233. package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +0 -257
  234. package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +0 -611
  235. package/test/units/static/JBPermissions/JBPermissionsSetup.sol +0 -20
  236. package/test/units/static/JBPermissions/TestHasPermission.sol +0 -50
  237. package/test/units/static/JBPermissions/TestHasPermissions.sol +0 -93
  238. package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +0 -64
  239. package/test/units/static/JBPrices/JBPricesSetup.sol +0 -32
  240. package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +0 -107
  241. package/test/units/static/JBPrices/TestPricePerUnitOf.sol +0 -132
  242. package/test/units/static/JBPrices/TestPrices.sol +0 -265
  243. package/test/units/static/JBProjects/JBProjectsSetup.sol +0 -22
  244. package/test/units/static/JBProjects/TestCreateFor.sol +0 -71
  245. package/test/units/static/JBProjects/TestInitialProject.sol +0 -21
  246. package/test/units/static/JBProjects/TestInterfaces.sol +0 -26
  247. package/test/units/static/JBProjects/TestSetResolver.sol +0 -37
  248. package/test/units/static/JBProjects/TestTokenUri.sol +0 -40
  249. package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +0 -108
  250. package/test/units/static/JBRulesets/JBRulesetsSetup.sol +0 -24
  251. package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +0 -265
  252. package/test/units/static/JBRulesets/TestCurrentOf.sol +0 -242
  253. package/test/units/static/JBRulesets/TestGetRulesetOf.sol +0 -100
  254. package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +0 -260
  255. package/test/units/static/JBRulesets/TestRulesets.sol +0 -632
  256. package/test/units/static/JBRulesets/TestRulesetsOf.sol +0 -37
  257. package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +0 -522
  258. package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +0 -96
  259. package/test/units/static/JBSplits/JBSplitsSetup.sol +0 -26
  260. package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +0 -552
  261. package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +0 -377
  262. package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +0 -267
  263. package/test/units/static/JBSplits/TestSplitsOf.sol +0 -24
  264. package/test/units/static/JBSplits/TestSplitsPacking.sol +0 -36
  265. package/test/units/static/JBSurplus/TestSurplusFuzz.sol +0 -160
  266. package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +0 -45
  267. package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +0 -536
  268. package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +0 -463
  269. package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +0 -135
  270. package/test/units/static/JBTerminalStore/TestPreviewCashOutFrom.sol +0 -476
  271. package/test/units/static/JBTerminalStore/TestPreviewPayFrom.sol +0 -494
  272. package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +0 -652
  273. package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +0 -744
  274. package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +0 -289
  275. package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +0 -138
  276. package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +0 -415
  277. package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +0 -219
  278. package/test/units/static/JBTokens/JBTokensSetup.sol +0 -32
  279. package/test/units/static/JBTokens/TestBurnFrom.sol +0 -107
  280. package/test/units/static/JBTokens/TestClaimTokensFor.sol +0 -110
  281. package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +0 -92
  282. package/test/units/static/JBTokens/TestMintFor.sol +0 -100
  283. package/test/units/static/JBTokens/TestSetTokenFor.sol +0 -98
  284. package/test/units/static/JBTokens/TestTotalBalanceOf.sol +0 -65
  285. package/test/units/static/JBTokens/TestTotalSupplyOf.sol +0 -56
  286. 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
- }