@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.
- package/foundry.lock +1 -7
- package/foundry.toml +1 -1
- package/package.json +19 -7
- package/src/JBController.sol +19 -1
- package/src/JBMultiTerminal.sol +68 -34
- package/src/JBTerminalStore.sol +6 -6
- package/src/interfaces/IJBController.sol +4 -1
- package/src/libraries/JBFees.sol +47 -9
- package/src/libraries/JBPayoutSplitGroupLib.sol +2 -2
- package/src/periphery/JBMatchingPriceFeed.sol +1 -1
- package/test/mock/MockMaliciousBeneficiary.sol +15 -15
- package/ADMINISTRATION.md +0 -103
- package/ARCHITECTURE.md +0 -133
- package/AUDIT_INSTRUCTIONS.md +0 -139
- package/RISKS.md +0 -215
- package/SKILLS.md +0 -55
- package/STYLE_GUIDE.md +0 -610
- package/USER_JOURNEYS.md +0 -215
- package/script/Deploy.s.sol +0 -124
- package/script/DeployPeriphery.s.sol +0 -354
- package/slither-ci.config.json +0 -10
- package/test/AuditFixes.t.sol +0 -808
- package/test/ComprehensiveInvariant.t.sol +0 -306
- package/test/CoreExploitTests.t.sol +0 -2741
- package/test/EconomicSimulation.t.sol +0 -348
- package/test/EntryPointPermutations.t.sol +0 -684
- package/test/FlashLoanAttacks.t.sol +0 -797
- package/test/PermissionEscalation.t.sol +0 -711
- package/test/PermissionsInvariant.t.sol +0 -403
- package/test/RulesetTransitions.t.sol +0 -713
- package/test/SplitLoopTests.t.sol +0 -752
- package/test/TestAccessToFunds.sol +0 -2683
- package/test/TestAuditResponseDesignProofs.sol +0 -434
- package/test/TestCashOut.sol +0 -198
- package/test/TestCashOutCountFor.sol +0 -271
- package/test/TestCashOutHooks.sol +0 -351
- package/test/TestCashOutTimingEdge.sol +0 -241
- package/test/TestDataHookFuzzing.sol +0 -524
- package/test/TestDurationUnderflow.sol +0 -233
- package/test/TestFeeFreeCashOutBypass.sol +0 -949
- package/test/TestFeeProcessingFailure.sol +0 -218
- package/test/TestFees.sol +0 -619
- package/test/TestForwardedTokenConsumption.sol +0 -425
- package/test/TestInterfaceSupport.sol +0 -81
- package/test/TestJBERC20Inheritance.sol +0 -103
- package/test/TestL2SequencerPriceFeed.sol +0 -292
- package/test/TestLaunchProject.sol +0 -188
- package/test/TestMetaTx.sol +0 -217
- package/test/TestMetadataOffsetOverflow.sol +0 -179
- package/test/TestMetadataParserLib.sol +0 -471
- package/test/TestMigrationHeldFees.sol +0 -255
- package/test/TestMintTokensOf.sol +0 -185
- package/test/TestMultiTerminalSurplus.sol +0 -348
- package/test/TestMultiTokenSurplus.sol +0 -202
- package/test/TestMultipleAccessLimits.sol +0 -664
- package/test/TestPayBurnRedeemFlow.sol +0 -195
- package/test/TestPayHooks.sol +0 -209
- package/test/TestPermissions.sol +0 -324
- package/test/TestPermissionsEdge.sol +0 -290
- package/test/TestPermit2DataHook.t.sol +0 -360
- package/test/TestPermit2Terminal.sol +0 -372
- package/test/TestRulesetQueueing.sol +0 -1025
- package/test/TestRulesetQueuingStress.sol +0 -806
- package/test/TestRulesetWeightCaching.sol +0 -178
- package/test/TestSplits.sol +0 -391
- package/test/TestTerminalMigration.sol +0 -274
- package/test/TestTerminalPreviewParity.sol +0 -208
- package/test/TestTokenFlow.sol +0 -191
- package/test/TestWeightCacheStaleAfterRejection.sol +0 -303
- package/test/WeirdTokenTests.t.sol +0 -817
- package/test/audit/CashOutReenterPay.t.sol +0 -501
- package/test/audit/CodexHeldFeeRounding.t.sol +0 -159
- package/test/audit/CodexMigrationFeeFailure.t.sol +0 -163
- package/test/audit/CrossTerminalSurplusSpoof.t.sol +0 -140
- package/test/audit/CycledSurplusAllowanceReset.t.sol +0 -184
- package/test/audit/FeeFreeSurplusLifecycle.t.sol +0 -399
- package/test/audit/FeeFreeSurplusStale.t.sol +0 -248
- package/test/audit/USDTVoidReturnCompat.t.sol +0 -525
- package/test/fork/TestChainlinkPriceFeedFork.sol +0 -254
- package/test/fork/TestSequencerPriceFeedFork.sol +0 -168
- package/test/fork/TestTerminalPreviewParityFork.sol +0 -108
- package/test/formal/BondingCurveProperties.t.sol +0 -420
- package/test/formal/FeeProperties.t.sol +0 -252
- package/test/invariants/Phase3DeepInvariant.t.sol +0 -412
- package/test/invariants/RulesetsInvariant.t.sol +0 -125
- package/test/invariants/TerminalStoreInvariant.t.sol +0 -227
- package/test/invariants/TokensInvariant.t.sol +0 -195
- package/test/invariants/handlers/ComprehensiveHandler.sol +0 -303
- package/test/invariants/handlers/EconomicHandler.sol +0 -377
- package/test/invariants/handlers/Phase3Handler.sol +0 -443
- package/test/invariants/handlers/RulesetsHandler.sol +0 -115
- package/test/invariants/handlers/TerminalStoreHandler.sol +0 -151
- package/test/invariants/handlers/TokensHandler.sol +0 -126
- package/test/regression/HoldFeesCashOutReserved.t.sol +0 -415
- package/test/regression/WeightCacheBoundary.t.sol +0 -291
- package/test/trees/JBController/burnTokensOf.tree +0 -9
- package/test/trees/JBController/claimTokensFor.tree +0 -5
- package/test/trees/JBController/deployERC20For.tree +0 -5
- package/test/trees/JBController/getRulesetOf.tree +0 -5
- package/test/trees/JBController/launchProjectFor.tree +0 -12
- package/test/trees/JBController/launchRulesetsFor.tree +0 -8
- package/test/trees/JBController/migrateController.tree +0 -12
- package/test/trees/JBController/mintTokensOf.tree +0 -12
- package/test/trees/JBController/payReservedTokenToTerminal.tree +0 -8
- package/test/trees/JBController/receiveMigrationFrom.tree +0 -4
- package/test/trees/JBController/sendReservedTokensToSplitsOf.tree +0 -12
- package/test/trees/JBController/setMetadataOf.tree +0 -5
- package/test/trees/JBController/setSplitGroupsOf.tree +0 -5
- package/test/trees/JBController/setTokenFor.tree +0 -5
- package/test/trees/JBController/transferCreditsFrom.tree +0 -8
- package/test/trees/JBDirectory/primaryTerminalOf.tree +0 -8
- package/test/trees/JBDirectory/setControllerOf.tree +0 -11
- package/test/trees/JBDirectory/setPrimaryTerminalOf.tree +0 -15
- package/test/trees/JBDirectory/setTerminalsOf.tree +0 -11
- package/test/trees/JBERC20/initialize.tree +0 -7
- package/test/trees/JBERC20/name.tree +0 -5
- package/test/trees/JBERC20/nonces.tree +0 -5
- package/test/trees/JBERC20/symbol.tree +0 -5
- package/test/trees/JBFeelessAddresses/setFeelessAddress.tree +0 -5
- package/test/trees/JBFeelessAddresses/supportsInterface.tree +0 -5
- package/test/trees/JBFundAccessLimits/payoutLimitOf.tree +0 -5
- package/test/trees/JBFundAccessLimits/payoutLimitsOf.tree +0 -8
- package/test/trees/JBFundAccessLimits/setFundAccessLimitsFor.tree +0 -18
- package/test/trees/JBFundAccessLimits/surplusAllowanceOf.tree +0 -5
- package/test/trees/JBFundAccessLimits/surplusAllowancesOf.tree +0 -8
- package/test/trees/JBMetadataResolver/getDataFor.tree +0 -8
- package/test/trees/JBMultiTerminal/accountingContextsOf.tree +0 -5
- package/test/trees/JBMultiTerminal/addAccountingContextsFor.tree +0 -10
- package/test/trees/JBMultiTerminal/addToBalanceOf.tree +0 -23
- package/test/trees/JBMultiTerminal/cashOutTokensOf.tree +0 -23
- package/test/trees/JBMultiTerminal/executePayout.tree +0 -32
- package/test/trees/JBMultiTerminal/executeProcessFee.tree +0 -14
- package/test/trees/JBMultiTerminal/migrateBalanceOf.tree +0 -12
- package/test/trees/JBMultiTerminal/pay.tree +0 -23
- package/test/trees/JBMultiTerminal/processHeldFeesOf.tree +0 -8
- package/test/trees/JBMultiTerminal/sendPayoutsOf.tree +0 -34
- package/test/trees/JBMultiTerminal/useAllowanceOf.tree +0 -16
- package/test/trees/JBPermissions/hasPermission.tree +0 -8
- package/test/trees/JBPermissions/hasPermissions.tree +0 -8
- package/test/trees/JBPermissions/setPermissionsFor.tree +0 -5
- package/test/trees/JBPrices/addPriceFeedFor.tree +0 -14
- package/test/trees/JBPrices/pricePerUnitOf.tree +0 -11
- package/test/trees/JBProjects/createFor.tree +0 -11
- package/test/trees/JBProjects/setTokenUriResolver.tree +0 -5
- package/test/trees/JBProjects/supportsInterface.tree +0 -9
- package/test/trees/JBProjects/tokenURI.tree +0 -5
- package/test/trees/JBRulesets/currentApprovalStatusForLatestRulesetOf.tree +0 -8
- package/test/trees/JBRulesets/currentOf.tree +0 -12
- package/test/trees/JBRulesets/getRulesetOf.tree +0 -5
- package/test/trees/JBRulesets/latestQueuedRulesetOf.tree +0 -10
- package/test/trees/JBRulesets/rulesetsOf.tree +0 -11
- package/test/trees/JBRulesets/upcomingRulesetOf.tree +0 -20
- package/test/trees/JBRulesets/updateRulesetWeightCache.tree +0 -5
- package/test/trees/JBSplits/setSplitGroupsOf.tree +0 -17
- package/test/trees/JBSplits/splitsOf.tree +0 -5
- package/test/trees/JBTerminalStore/currentReclaimableSurplusOf.tree +0 -16
- package/test/trees/JBTerminalStore/currentSurplusOf.tree +0 -25
- package/test/trees/JBTerminalStore/currentTotalSurplusOf.tree +0 -5
- package/test/trees/JBTerminalStore/recordCashOutsFor.tree +0 -16
- package/test/trees/JBTerminalStore/recordPaymentFrom.tree +0 -14
- package/test/trees/JBTerminalStore/recordPayoutFor.tree +0 -10
- package/test/trees/JBTerminalStore/recordTerminalMigration.tree +0 -5
- package/test/trees/JBTerminalStore/recordUsedAllowanceOf.tree +0 -10
- package/test/trees/JBTokens/burnFrom.tree +0 -10
- package/test/trees/JBTokens/claimTokensFor.tree +0 -10
- package/test/trees/JBTokens/deployERC20For.tree +0 -12
- package/test/trees/JBTokens/mintFor.tree +0 -10
- package/test/trees/JBTokens/setTokenFor.tree +0 -11
- package/test/trees/JBTokens/totalBalanceOf.tree +0 -5
- package/test/trees/JBTokens/totalSupplyOf.tree +0 -5
- package/test/trees/JBTokens/transferCreditsFrom.tree +0 -8
- package/test/trees/mintTokensOf.tree +0 -12
- package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +0 -223
- package/test/units/static/JBController/JBControllerSetup.sol +0 -50
- package/test/units/static/JBController/TestBurnTokensOf.sol +0 -114
- package/test/units/static/JBController/TestClaimTokensFor.sol +0 -63
- package/test/units/static/JBController/TestDeployErc20For.sol +0 -86
- package/test/units/static/JBController/TestLaunchProjectFor.sol +0 -302
- package/test/units/static/JBController/TestLaunchRulesetsFor.sol +0 -342
- package/test/units/static/JBController/TestMigrateController.sol +0 -157
- package/test/units/static/JBController/TestMintTokensOfUnits.sol +0 -111
- package/test/units/static/JBController/TestOmnichainRulesetOperator.sol +0 -324
- package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +0 -74
- package/test/units/static/JBController/TestPreviewMintOf.sol +0 -117
- package/test/units/static/JBController/TestReceiveMigrationFrom.sol +0 -99
- package/test/units/static/JBController/TestRulesetViews.sol +0 -225
- package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +0 -615
- package/test/units/static/JBController/TestSetSplitGroupsOf.sol +0 -68
- package/test/units/static/JBController/TestSetTokenFor.sol +0 -239
- package/test/units/static/JBController/TestSetUriOf.sol +0 -57
- package/test/units/static/JBController/TestTransferCreditsFrom.sol +0 -169
- package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +0 -211
- package/test/units/static/JBDirectory/JBDirectorySetup.sol +0 -26
- package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +0 -126
- package/test/units/static/JBDirectory/TestSetControllerOf.sol +0 -183
- package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +0 -104
- package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +0 -179
- package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +0 -137
- package/test/units/static/JBERC20/JBERC20Setup.sol +0 -34
- package/test/units/static/JBERC20/SigUtils.sol +0 -36
- package/test/units/static/JBERC20/TestInitialize.sol +0 -60
- package/test/units/static/JBERC20/TestName.sol +0 -30
- package/test/units/static/JBERC20/TestNonces.sol +0 -62
- package/test/units/static/JBERC20/TestSymbol.sol +0 -31
- package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +0 -22
- package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +0 -30
- package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +0 -35
- package/test/units/static/JBFees/TestFeesFuzz.sol +0 -79
- package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +0 -16
- package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +0 -71
- package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +0 -24
- package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +0 -163
- package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +0 -59
- package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +0 -101
- package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +0 -189
- package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +0 -64
- package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +0 -102
- package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +0 -90
- package/test/units/static/JBMetadataResolver/TestMetadataResolverEdgeCases.sol +0 -247
- package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +0 -229
- package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +0 -50
- package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +0 -72
- package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +0 -289
- package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +0 -474
- package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +0 -624
- package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +0 -578
- package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +0 -202
- package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +0 -222
- package/test/units/static/JBMultiTerminal/TestPay.sol +0 -604
- package/test/units/static/JBMultiTerminal/TestPreviewCashOutFrom.sol +0 -117
- package/test/units/static/JBMultiTerminal/TestPreviewPayFor.sol +0 -114
- package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +0 -228
- package/test/units/static/JBMultiTerminal/TestSelfPayRevert.sol +0 -55
- package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +0 -257
- package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +0 -611
- package/test/units/static/JBPermissions/JBPermissionsSetup.sol +0 -20
- package/test/units/static/JBPermissions/TestHasPermission.sol +0 -50
- package/test/units/static/JBPermissions/TestHasPermissions.sol +0 -93
- package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +0 -64
- package/test/units/static/JBPrices/JBPricesSetup.sol +0 -32
- package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +0 -107
- package/test/units/static/JBPrices/TestPricePerUnitOf.sol +0 -132
- package/test/units/static/JBPrices/TestPrices.sol +0 -265
- package/test/units/static/JBProjects/JBProjectsSetup.sol +0 -22
- package/test/units/static/JBProjects/TestCreateFor.sol +0 -71
- package/test/units/static/JBProjects/TestInitialProject.sol +0 -21
- package/test/units/static/JBProjects/TestInterfaces.sol +0 -26
- package/test/units/static/JBProjects/TestSetResolver.sol +0 -37
- package/test/units/static/JBProjects/TestTokenUri.sol +0 -40
- package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +0 -108
- package/test/units/static/JBRulesets/JBRulesetsSetup.sol +0 -24
- package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +0 -265
- package/test/units/static/JBRulesets/TestCurrentOf.sol +0 -242
- package/test/units/static/JBRulesets/TestGetRulesetOf.sol +0 -100
- package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +0 -260
- package/test/units/static/JBRulesets/TestRulesets.sol +0 -632
- package/test/units/static/JBRulesets/TestRulesetsOf.sol +0 -37
- package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +0 -522
- package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +0 -96
- package/test/units/static/JBSplits/JBSplitsSetup.sol +0 -26
- package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +0 -552
- package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +0 -377
- package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +0 -267
- package/test/units/static/JBSplits/TestSplitsOf.sol +0 -24
- package/test/units/static/JBSplits/TestSplitsPacking.sol +0 -36
- package/test/units/static/JBSurplus/TestSurplusFuzz.sol +0 -160
- package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +0 -45
- package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +0 -536
- package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +0 -463
- package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +0 -135
- package/test/units/static/JBTerminalStore/TestPreviewCashOutFrom.sol +0 -476
- package/test/units/static/JBTerminalStore/TestPreviewPayFrom.sol +0 -494
- package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +0 -652
- package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +0 -744
- package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +0 -289
- package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +0 -138
- package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +0 -415
- package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +0 -219
- package/test/units/static/JBTokens/JBTokensSetup.sol +0 -32
- package/test/units/static/JBTokens/TestBurnFrom.sol +0 -107
- package/test/units/static/JBTokens/TestClaimTokensFor.sol +0 -110
- package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +0 -92
- package/test/units/static/JBTokens/TestMintFor.sol +0 -100
- package/test/units/static/JBTokens/TestSetTokenFor.sol +0 -98
- package/test/units/static/JBTokens/TestTotalBalanceOf.sol +0 -65
- package/test/units/static/JBTokens/TestTotalSupplyOf.sol +0 -56
- 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
|
-
}
|