@bananapus/core-v6 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +112 -0
- package/SKILLS.md +151 -0
- package/docs/book.css +13 -0
- package/docs/book.toml +12 -0
- package/docs/solidity.min.js +74 -0
- package/docs/src/README.md +703 -0
- package/docs/src/SUMMARY.md +94 -0
- package/docs/src/src/JBChainlinkV3PriceFeed.sol/contract.JBChainlinkV3PriceFeed.md +83 -0
- package/docs/src/src/JBChainlinkV3SequencerPriceFeed.sol/contract.JBChainlinkV3SequencerPriceFeed.md +88 -0
- package/docs/src/src/JBController.sol/contract.JBController.md +1121 -0
- package/docs/src/src/JBDeadline.sol/contract.JBDeadline.md +84 -0
- package/docs/src/src/JBDirectory.sol/contract.JBDirectory.md +294 -0
- package/docs/src/src/JBERC20.sol/contract.JBERC20.md +190 -0
- package/docs/src/src/JBFeelessAddresses.sol/contract.JBFeelessAddresses.md +80 -0
- package/docs/src/src/JBFundAccessLimits.sol/contract.JBFundAccessLimits.md +253 -0
- package/docs/src/src/JBMultiTerminal.sol/contract.JBMultiTerminal.md +1472 -0
- package/docs/src/src/JBPermissions.sol/contract.JBPermissions.md +199 -0
- package/docs/src/src/JBPrices.sol/contract.JBPrices.md +154 -0
- package/docs/src/src/JBProjects.sol/contract.JBProjects.md +131 -0
- package/docs/src/src/JBRulesets.sol/contract.JBRulesets.md +677 -0
- package/docs/src/src/JBSplits.sol/contract.JBSplits.md +237 -0
- package/docs/src/src/JBTerminalStore.sol/contract.JBTerminalStore.md +591 -0
- package/docs/src/src/JBTokens.sol/contract.JBTokens.md +353 -0
- package/docs/src/src/README.md +25 -0
- package/docs/src/src/abstract/JBControlled.sol/abstract.JBControlled.md +64 -0
- package/docs/src/src/abstract/JBPermissioned.sol/abstract.JBPermissioned.md +84 -0
- package/docs/src/src/abstract/README.md +5 -0
- package/docs/src/src/enums/JBApprovalStatus.sol/enum.JBApprovalStatus.md +17 -0
- package/docs/src/src/enums/README.md +4 -0
- package/docs/src/src/interfaces/IJBCashOutHook.sol/interface.IJBCashOutHook.md +29 -0
- package/docs/src/src/interfaces/IJBCashOutTerminal.sol/interface.IJBCashOutTerminal.md +57 -0
- package/docs/src/src/interfaces/IJBControlled.sol/interface.IJBControlled.md +12 -0
- package/docs/src/src/interfaces/IJBController.sol/interface.IJBController.md +334 -0
- package/docs/src/src/interfaces/IJBDirectory.sol/interface.IJBDirectory.md +108 -0
- package/docs/src/src/interfaces/IJBDirectoryAccessControl.sol/interface.IJBDirectoryAccessControl.md +19 -0
- package/docs/src/src/interfaces/IJBFeeTerminal.sol/interface.IJBFeeTerminal.md +91 -0
- package/docs/src/src/interfaces/IJBFeelessAddresses.sol/interface.IJBFeelessAddresses.md +26 -0
- package/docs/src/src/interfaces/IJBFundAccessLimits.sol/interface.IJBFundAccessLimits.md +88 -0
- package/docs/src/src/interfaces/IJBMigratable.sol/interface.IJBMigratable.md +29 -0
- package/docs/src/src/interfaces/IJBMultiTerminal.sol/interface.IJBMultiTerminal.md +50 -0
- package/docs/src/src/interfaces/IJBPayHook.sol/interface.IJBPayHook.md +28 -0
- package/docs/src/src/interfaces/IJBPayoutTerminal.sol/interface.IJBPayoutTerminal.md +105 -0
- package/docs/src/src/interfaces/IJBPermissioned.sol/interface.IJBPermissioned.md +12 -0
- package/docs/src/src/interfaces/IJBPermissions.sol/interface.IJBPermissions.md +74 -0
- package/docs/src/src/interfaces/IJBPermitTerminal.sol/interface.IJBPermitTerminal.md +15 -0
- package/docs/src/src/interfaces/IJBPriceFeed.sol/interface.IJBPriceFeed.md +12 -0
- package/docs/src/src/interfaces/IJBPrices.sol/interface.IJBPrices.md +74 -0
- package/docs/src/src/interfaces/IJBProjectUriRegistry.sol/interface.IJBProjectUriRegistry.md +19 -0
- package/docs/src/src/interfaces/IJBProjects.sol/interface.IJBProjects.md +49 -0
- package/docs/src/src/interfaces/IJBRulesetApprovalHook.sol/interface.IJBRulesetApprovalHook.md +35 -0
- package/docs/src/src/interfaces/IJBRulesetDataHook.sol/interface.IJBRulesetDataHook.md +97 -0
- package/docs/src/src/interfaces/IJBRulesets.sol/interface.IJBRulesets.md +165 -0
- package/docs/src/src/interfaces/IJBSplitHook.sol/interface.IJBSplitHook.md +31 -0
- package/docs/src/src/interfaces/IJBSplits.sol/interface.IJBSplits.md +35 -0
- package/docs/src/src/interfaces/IJBTerminal.sol/interface.IJBTerminal.md +141 -0
- package/docs/src/src/interfaces/IJBTerminalStore.sol/interface.IJBTerminalStore.md +198 -0
- package/docs/src/src/interfaces/IJBToken.sol/interface.IJBToken.md +54 -0
- package/docs/src/src/interfaces/IJBTokenUriResolver.sol/interface.IJBTokenUriResolver.md +12 -0
- package/docs/src/src/interfaces/IJBTokens.sol/interface.IJBTokens.md +151 -0
- package/docs/src/src/interfaces/README.md +33 -0
- package/docs/src/src/libraries/JBCashOuts.sol/library.JBCashOuts.md +40 -0
- package/docs/src/src/libraries/JBConstants.sol/library.JBConstants.md +52 -0
- package/docs/src/src/libraries/JBCurrencyIds.sol/library.JBCurrencyIds.md +19 -0
- package/docs/src/src/libraries/JBFees.sol/library.JBFees.md +52 -0
- package/docs/src/src/libraries/JBFixedPointNumber.sol/library.JBFixedPointNumber.md +12 -0
- package/docs/src/src/libraries/JBMetadataResolver.sol/library.JBMetadataResolver.md +242 -0
- package/docs/src/src/libraries/JBRulesetMetadataResolver.sol/library.JBRulesetMetadataResolver.md +180 -0
- package/docs/src/src/libraries/JBSplitGroupIds.sol/library.JBSplitGroupIds.md +14 -0
- package/docs/src/src/libraries/JBSurplus.sol/library.JBSurplus.md +44 -0
- package/docs/src/src/libraries/README.md +12 -0
- package/docs/src/src/periphery/JBDeadline1Day.sol/contract.JBDeadline1Day.md +15 -0
- package/docs/src/src/periphery/JBDeadline3Days.sol/contract.JBDeadline3Days.md +15 -0
- package/docs/src/src/periphery/JBDeadline3Hours.sol/contract.JBDeadline3Hours.md +15 -0
- package/docs/src/src/periphery/JBDeadline7Days.sol/contract.JBDeadline7Days.md +15 -0
- package/docs/src/src/periphery/JBMatchingPriceFeed.sol/contract.JBMatchingPriceFeed.md +22 -0
- package/docs/src/src/periphery/README.md +8 -0
- package/docs/src/src/structs/JBAccountingContext.sol/struct.JBAccountingContext.md +20 -0
- package/docs/src/src/structs/JBAfterCashOutRecordedContext.sol/struct.JBAfterCashOutRecordedContext.md +43 -0
- package/docs/src/src/structs/JBAfterPayRecordedContext.sol/struct.JBAfterPayRecordedContext.md +42 -0
- package/docs/src/src/structs/JBBeforeCashOutRecordedContext.sol/struct.JBBeforeCashOutRecordedContext.md +45 -0
- package/docs/src/src/structs/JBBeforePayRecordedContext.sol/struct.JBBeforePayRecordedContext.md +41 -0
- package/docs/src/src/structs/JBCashOutHookSpecification.sol/struct.JBCashOutHookSpecification.md +22 -0
- package/docs/src/src/structs/JBCurrencyAmount.sol/struct.JBCurrencyAmount.md +17 -0
- package/docs/src/src/structs/JBFee.sol/struct.JBFee.md +20 -0
- package/docs/src/src/structs/JBFundAccessLimitGroup.sol/struct.JBFundAccessLimitGroup.md +39 -0
- package/docs/src/src/structs/JBPayHookSpecification.sol/struct.JBPayHookSpecification.md +22 -0
- package/docs/src/src/structs/JBPermissionsData.sol/struct.JBPermissionsData.md +21 -0
- package/docs/src/src/structs/JBRuleset.sol/struct.JBRuleset.md +55 -0
- package/docs/src/src/structs/JBRulesetConfig.sol/struct.JBRulesetConfig.md +51 -0
- package/docs/src/src/structs/JBRulesetMetadata.sol/struct.JBRulesetMetadata.md +79 -0
- package/docs/src/src/structs/JBRulesetWeightCache.sol/struct.JBRulesetWeightCache.md +16 -0
- package/docs/src/src/structs/JBRulesetWithMetadata.sol/struct.JBRulesetWithMetadata.md +16 -0
- package/docs/src/src/structs/JBSingleAllowance.sol/struct.JBSingleAllowance.md +26 -0
- package/docs/src/src/structs/JBSplit.sol/struct.JBSplit.md +49 -0
- package/docs/src/src/structs/JBSplitGroup.sol/struct.JBSplitGroup.md +17 -0
- package/docs/src/src/structs/JBSplitHookContext.sol/struct.JBSplitHookContext.md +29 -0
- package/docs/src/src/structs/JBTerminalConfig.sol/struct.JBTerminalConfig.md +16 -0
- package/docs/src/src/structs/JBTokenAmount.sol/struct.JBTokenAmount.md +23 -0
- package/docs/src/src/structs/README.md +25 -0
- package/foundry.lock +11 -0
- package/foundry.toml +41 -0
- package/package.json +38 -0
- package/remappings.txt +1 -0
- package/script/Deploy.s.sol +111 -0
- package/script/DeployPeriphery.s.sol +287 -0
- package/script/helpers/CoreDeploymentLib.sol +121 -0
- package/slither-ci.config.json +10 -0
- package/sphinx.lock +507 -0
- package/src/JBChainlinkV3PriceFeed.sol +77 -0
- package/src/JBChainlinkV3SequencerPriceFeed.sol +75 -0
- package/src/JBController.sol +1186 -0
- package/src/JBDeadline.sol +73 -0
- package/src/JBDirectory.sol +343 -0
- package/src/JBERC20.sol +131 -0
- package/src/JBFeelessAddresses.sol +54 -0
- package/src/JBFundAccessLimits.sol +308 -0
- package/src/JBMultiTerminal.sol +2024 -0
- package/src/JBPermissions.sol +252 -0
- package/src/JBPrices.sol +227 -0
- package/src/JBProjects.sol +126 -0
- package/src/JBRulesets.sol +1093 -0
- package/src/JBSplits.sol +324 -0
- package/src/JBTerminalStore.sol +908 -0
- package/src/JBTokens.sol +376 -0
- package/src/abstract/JBControlled.sol +48 -0
- package/src/abstract/JBPermissioned.sol +77 -0
- package/src/enums/JBApprovalStatus.sol +12 -0
- package/src/interfaces/IJBCashOutHook.sol +15 -0
- package/src/interfaces/IJBCashOutTerminal.sol +51 -0
- package/src/interfaces/IJBControlled.sol +10 -0
- package/src/interfaces/IJBController.sol +280 -0
- package/src/interfaces/IJBDirectory.sol +69 -0
- package/src/interfaces/IJBDirectoryAccessControl.sol +15 -0
- package/src/interfaces/IJBFeeTerminal.sol +61 -0
- package/src/interfaces/IJBFeelessAddresses.sol +17 -0
- package/src/interfaces/IJBFundAccessLimits.sol +94 -0
- package/src/interfaces/IJBMigratable.sol +24 -0
- package/src/interfaces/IJBMultiTerminal.sol +36 -0
- package/src/interfaces/IJBPayHook.sol +14 -0
- package/src/interfaces/IJBPayoutTerminal.sol +92 -0
- package/src/interfaces/IJBPermissioned.sol +10 -0
- package/src/interfaces/IJBPermissions.sol +71 -0
- package/src/interfaces/IJBPermitTerminal.sol +14 -0
- package/src/interfaces/IJBPriceFeed.sol +10 -0
- package/src/interfaces/IJBPrices.sol +65 -0
- package/src/interfaces/IJBProjectUriRegistry.sol +15 -0
- package/src/interfaces/IJBProjects.sol +27 -0
- package/src/interfaces/IJBRulesetApprovalHook.sol +21 -0
- package/src/interfaces/IJBRulesetDataHook.sol +56 -0
- package/src/interfaces/IJBRulesets.sol +151 -0
- package/src/interfaces/IJBSplitHook.sol +16 -0
- package/src/interfaces/IJBSplits.sol +28 -0
- package/src/interfaces/IJBTerminal.sol +120 -0
- package/src/interfaces/IJBTerminalStore.sol +225 -0
- package/src/interfaces/IJBToken.sol +39 -0
- package/src/interfaces/IJBTokenUriResolver.sol +10 -0
- package/src/interfaces/IJBTokens.sol +113 -0
- package/src/libraries/JBCashOuts.sol +120 -0
- package/src/libraries/JBConstants.sol +14 -0
- package/src/libraries/JBCurrencyIds.sol +7 -0
- package/src/libraries/JBFees.sol +28 -0
- package/src/libraries/JBFixedPointNumber.sol +12 -0
- package/src/libraries/JBMetadataResolver.sol +306 -0
- package/src/libraries/JBRulesetMetadataResolver.sol +160 -0
- package/src/libraries/JBSplitGroupIds.sol +7 -0
- package/src/libraries/JBSurplus.sol +40 -0
- package/src/periphery/JBDeadline1Day.sol +8 -0
- package/src/periphery/JBDeadline3Days.sol +8 -0
- package/src/periphery/JBDeadline3Hours.sol +8 -0
- package/src/periphery/JBDeadline7Days.sol +8 -0
- package/src/periphery/JBMatchingPriceFeed.sol +13 -0
- package/src/structs/JBAccountingContext.sol +12 -0
- package/src/structs/JBAfterCashOutRecordedContext.sol +30 -0
- package/src/structs/JBAfterPayRecordedContext.sol +29 -0
- package/src/structs/JBBeforeCashOutRecordedContext.sol +31 -0
- package/src/structs/JBBeforePayRecordedContext.sol +28 -0
- package/src/structs/JBCashOutHookSpecification.sol +15 -0
- package/src/structs/JBCurrencyAmount.sol +10 -0
- package/src/structs/JBFee.sol +12 -0
- package/src/structs/JBFundAccessLimitGroup.sol +28 -0
- package/src/structs/JBPayHookSpecification.sol +15 -0
- package/src/structs/JBPermissionsData.sol +13 -0
- package/src/structs/JBRuleset.sol +42 -0
- package/src/structs/JBRulesetConfig.sol +43 -0
- package/src/structs/JBRulesetMetadata.sol +56 -0
- package/src/structs/JBRulesetWeightCache.sol +9 -0
- package/src/structs/JBRulesetWithMetadata.sol +12 -0
- package/src/structs/JBSingleAllowance.sol +16 -0
- package/src/structs/JBSplit.sol +37 -0
- package/src/structs/JBSplitGroup.sol +12 -0
- package/src/structs/JBSplitHookContext.sol +20 -0
- package/src/structs/JBTerminalConfig.sol +12 -0
- package/src/structs/JBTokenAmount.sol +14 -0
- package/test/AuditExploits.t.sol +2710 -0
- package/test/ComprehensiveInvariant.t.sol +298 -0
- package/test/EconomicSimulation.t.sol +340 -0
- package/test/EntryPointPermutations.t.sol +671 -0
- package/test/FlashLoanAttacks.t.sol +792 -0
- package/test/PermissionEscalation.t.sol +679 -0
- package/test/RulesetTransitions.t.sol +699 -0
- package/test/SplitLoopTests.t.sol +731 -0
- package/test/TestAccessToFunds.sol +2644 -0
- package/test/TestCashOut.sol +185 -0
- package/test/TestCashOutCountFor.sol +272 -0
- package/test/TestCashOutHooks.sol +317 -0
- package/test/TestCashOutTimingEdge.sol +229 -0
- package/test/TestDurationUnderflow.sol +220 -0
- package/test/TestFeeProcessingFailure.sol +208 -0
- package/test/TestFees.sol +604 -0
- package/test/TestInterfaceSupport.sol +62 -0
- package/test/TestJBERC20Inheritance.sol +91 -0
- package/test/TestLaunchProject.sol +176 -0
- package/test/TestMetaTx.sol +203 -0
- package/test/TestMetadataParserLib.sol +438 -0
- package/test/TestMigrationHeldFees.sol +249 -0
- package/test/TestMintTokensOf.sol +172 -0
- package/test/TestMultiTokenSurplus.sol +206 -0
- package/test/TestMultipleAccessLimits.sol +642 -0
- package/test/TestPayBurnRedeemFlow.sol +180 -0
- package/test/TestPayHooks.sol +190 -0
- package/test/TestPermissions.sol +305 -0
- package/test/TestPermissionsEdge.sol +286 -0
- package/test/TestPermit2Terminal.sol +339 -0
- package/test/TestRulesetQueueing.sol +1001 -0
- package/test/TestRulesetQueuingStress.sol +778 -0
- package/test/TestRulesetWeightCaching.sol +177 -0
- package/test/TestSplits.sol +369 -0
- package/test/TestTerminalMigration.sol +167 -0
- package/test/TestTokenFlow.sol +174 -0
- package/test/WeirdTokenTests.t.sol +764 -0
- package/test/formal/BondingCurveProperties.t.sol +411 -0
- package/test/formal/FeeProperties.t.sol +246 -0
- package/test/helpers/JBTest.sol +129 -0
- package/test/helpers/MetadataResolverHelper.sol +116 -0
- package/test/helpers/TestBaseWorkflow.sol +317 -0
- package/test/invariants/Phase3DeepInvariant.t.sol +404 -0
- package/test/invariants/RulesetsInvariant.t.sol +115 -0
- package/test/invariants/TerminalStoreInvariant.t.sol +220 -0
- package/test/invariants/TokensInvariant.t.sol +184 -0
- package/test/invariants/handlers/ComprehensiveHandler.sol +285 -0
- package/test/invariants/handlers/EconomicHandler.sol +347 -0
- package/test/invariants/handlers/Phase3Handler.sol +414 -0
- package/test/invariants/handlers/RulesetsHandler.sol +111 -0
- package/test/invariants/handlers/TerminalStoreHandler.sol +146 -0
- package/test/invariants/handlers/TokensHandler.sol +127 -0
- package/test/mock/ERC2771ForwarderMock.sol +37 -0
- package/test/mock/MockERC20.sol +18 -0
- package/test/mock/MockMaliciousBeneficiary.sol +67 -0
- package/test/mock/MockMaliciousSplitHook.sol +42 -0
- package/test/mock/MockPriceFeed.sol +20 -0
- package/test/trees/JBController/burnTokensOf.tree +9 -0
- package/test/trees/JBController/claimTokensFor.tree +5 -0
- package/test/trees/JBController/deployERC20For.tree +5 -0
- package/test/trees/JBController/getRulesetOf.tree +5 -0
- package/test/trees/JBController/launchProjectFor.tree +12 -0
- package/test/trees/JBController/launchRulesetsFor.tree +8 -0
- package/test/trees/JBController/migrateController.tree +12 -0
- package/test/trees/JBController/mintTokensOf.tree +12 -0
- package/test/trees/JBController/payReservedTokenToTerminal.tree +8 -0
- package/test/trees/JBController/receiveMigrationFrom.tree +4 -0
- package/test/trees/JBController/sendReservedTokensToSplitsOf.tree +12 -0
- package/test/trees/JBController/setMetadataOf.tree +5 -0
- package/test/trees/JBController/setSplitGroupsOf.tree +5 -0
- package/test/trees/JBController/setTokenFor.tree +5 -0
- package/test/trees/JBController/transferCreditsFrom.tree +8 -0
- package/test/trees/JBDirectory/primaryTerminalOf.tree +8 -0
- package/test/trees/JBDirectory/setControllerOf.tree +11 -0
- package/test/trees/JBDirectory/setPrimaryTerminalOf.tree +15 -0
- package/test/trees/JBDirectory/setTerminalsOf.tree +11 -0
- package/test/trees/JBERC20/initialize.tree +7 -0
- package/test/trees/JBERC20/name.tree +5 -0
- package/test/trees/JBERC20/nonces.tree +5 -0
- package/test/trees/JBERC20/symbol.tree +5 -0
- package/test/trees/JBFeelessAddresses/setFeelessAddress.tree +5 -0
- package/test/trees/JBFeelessAddresses/supportsInterface.tree +5 -0
- package/test/trees/JBFundAccessLimits/payoutLimitOf.tree +5 -0
- package/test/trees/JBFundAccessLimits/payoutLimitsOf.tree +8 -0
- package/test/trees/JBFundAccessLimits/setFundAccessLimitsFor.tree +18 -0
- package/test/trees/JBFundAccessLimits/surplusAllowanceOf.tree +5 -0
- package/test/trees/JBFundAccessLimits/surplusAllowancesOf.tree +8 -0
- package/test/trees/JBMetadataResolver/getDataFor.tree +8 -0
- package/test/trees/JBMultiTerminal/accountingContextsOf.tree +5 -0
- package/test/trees/JBMultiTerminal/addAccountingContextsFor.tree +10 -0
- package/test/trees/JBMultiTerminal/addToBalanceOf.tree +23 -0
- package/test/trees/JBMultiTerminal/cashOutTokensOf.tree +23 -0
- package/test/trees/JBMultiTerminal/executePayout.tree +32 -0
- package/test/trees/JBMultiTerminal/executeProcessFee.tree +14 -0
- package/test/trees/JBMultiTerminal/migrateBalanceOf.tree +12 -0
- package/test/trees/JBMultiTerminal/pay.tree +23 -0
- package/test/trees/JBMultiTerminal/processHeldFeesOf.tree +8 -0
- package/test/trees/JBMultiTerminal/sendPayoutsOf.tree +34 -0
- package/test/trees/JBMultiTerminal/useAllowanceOf.tree +16 -0
- package/test/trees/JBPermissions/hasPermission.tree +8 -0
- package/test/trees/JBPermissions/hasPermissions.tree +8 -0
- package/test/trees/JBPermissions/setPermissionsFor.tree +5 -0
- package/test/trees/JBPrices/addPriceFeedFor.tree +14 -0
- package/test/trees/JBPrices/pricePerUnitOf.tree +11 -0
- package/test/trees/JBProjects/createFor.tree +11 -0
- package/test/trees/JBProjects/setTokenUriResolver.tree +5 -0
- package/test/trees/JBProjects/supportsInterface.tree +9 -0
- package/test/trees/JBProjects/tokenURI.tree +5 -0
- package/test/trees/JBRulesets/currentApprovalStatusForLatestRulesetOf.tree +8 -0
- package/test/trees/JBRulesets/currentOf.tree +12 -0
- package/test/trees/JBRulesets/getRulesetOf.tree +5 -0
- package/test/trees/JBRulesets/latestQueuedRulesetOf.tree +10 -0
- package/test/trees/JBRulesets/rulesetsOf.tree +11 -0
- package/test/trees/JBRulesets/upcomingRulesetOf.tree +20 -0
- package/test/trees/JBRulesets/updateRulesetWeightCache.tree +5 -0
- package/test/trees/JBSplits/setSplitGroupsOf.tree +17 -0
- package/test/trees/JBSplits/splitsOf.tree +5 -0
- package/test/trees/JBTerminalStore/currentReclaimableSurplusOf.tree +16 -0
- package/test/trees/JBTerminalStore/currentSurplusOf.tree +25 -0
- package/test/trees/JBTerminalStore/currentTotalSurplusOf.tree +5 -0
- package/test/trees/JBTerminalStore/recordCashOutsFor.tree +16 -0
- package/test/trees/JBTerminalStore/recordPaymentFrom.tree +14 -0
- package/test/trees/JBTerminalStore/recordPayoutFor.tree +10 -0
- package/test/trees/JBTerminalStore/recordTerminalMigration.tree +5 -0
- package/test/trees/JBTerminalStore/recordUsedAllowanceOf.tree +10 -0
- package/test/trees/JBTokens/burnFrom.tree +10 -0
- package/test/trees/JBTokens/claimTokensFor.tree +10 -0
- package/test/trees/JBTokens/deployERC20For.tree +12 -0
- package/test/trees/JBTokens/mintFor.tree +10 -0
- package/test/trees/JBTokens/setTokenFor.tree +11 -0
- package/test/trees/JBTokens/totalBalanceOf.tree +5 -0
- package/test/trees/JBTokens/totalSupplyOf.tree +5 -0
- package/test/trees/JBTokens/transferCreditsFrom.tree +8 -0
- package/test/trees/mintTokensOf.tree +12 -0
- package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +220 -0
- package/test/units/static/JBController/JBControllerSetup.sol +40 -0
- package/test/units/static/JBController/TestBurnTokensOf.sol +107 -0
- package/test/units/static/JBController/TestClaimTokensFor.sol +60 -0
- package/test/units/static/JBController/TestDeployErc20For.sol +80 -0
- package/test/units/static/JBController/TestLaunchProjectFor.sol +282 -0
- package/test/units/static/JBController/TestLaunchRulesetsFor.sol +322 -0
- package/test/units/static/JBController/TestMigrateController.sol +148 -0
- package/test/units/static/JBController/TestMintTokensOfUnits.sol +102 -0
- package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +71 -0
- package/test/units/static/JBController/TestReceiveMigrationFrom.sol +95 -0
- package/test/units/static/JBController/TestRulesetViews.sol +219 -0
- package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +595 -0
- package/test/units/static/JBController/TestSetSplitGroupsOf.sol +63 -0
- package/test/units/static/JBController/TestSetTokenFor.sol +227 -0
- package/test/units/static/JBController/TestSetUriOf.sol +53 -0
- package/test/units/static/JBController/TestTransferCreditsFrom.sol +159 -0
- package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +194 -0
- package/test/units/static/JBDirectory/JBDirectorySetup.sol +22 -0
- package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +122 -0
- package/test/units/static/JBDirectory/TestSetControllerOf.sol +173 -0
- package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +98 -0
- package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +169 -0
- package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +128 -0
- package/test/units/static/JBERC20/JBERC20Setup.sol +20 -0
- package/test/units/static/JBERC20/SigUtils.sol +34 -0
- package/test/units/static/JBERC20/TestInitialize.sol +54 -0
- package/test/units/static/JBERC20/TestName.sol +30 -0
- package/test/units/static/JBERC20/TestNonces.sol +59 -0
- package/test/units/static/JBERC20/TestSymbol.sol +31 -0
- package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +20 -0
- package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +29 -0
- package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +35 -0
- package/test/units/static/JBFees/TestFeesFuzz.sol +78 -0
- package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +16 -0
- package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +71 -0
- package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +21 -0
- package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +159 -0
- package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +56 -0
- package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +94 -0
- package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +182 -0
- package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +61 -0
- package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +96 -0
- package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +89 -0
- package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +227 -0
- package/test/units/static/JBMetadataResolver/TestMetadataResolverM20M21.sol +245 -0
- package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +39 -0
- package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +65 -0
- package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +313 -0
- package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +432 -0
- package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +478 -0
- package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +577 -0
- package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +176 -0
- package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +190 -0
- package/test/units/static/JBMultiTerminal/TestPay.sol +514 -0
- package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +29 -0
- package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +243 -0
- package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +310 -0
- package/test/units/static/JBPermissions/JBPermissionsSetup.sol +18 -0
- package/test/units/static/JBPermissions/TestHasPermission.sol +50 -0
- package/test/units/static/JBPermissions/TestHasPermissions.sol +93 -0
- package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +62 -0
- package/test/units/static/JBPrices/JBPricesSetup.sol +26 -0
- package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +102 -0
- package/test/units/static/JBPrices/TestPricePerUnitOf.sol +129 -0
- package/test/units/static/JBPrices/TestPrices.sol +262 -0
- package/test/units/static/JBProjects/JBProjectsSetup.sol +20 -0
- package/test/units/static/JBProjects/TestCreateFor.sol +69 -0
- package/test/units/static/JBProjects/TestInitialProject.sol +19 -0
- package/test/units/static/JBProjects/TestInterfaces.sol +27 -0
- package/test/units/static/JBProjects/TestSetResolver.sol +36 -0
- package/test/units/static/JBProjects/TestTokenUri.sol +38 -0
- package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +99 -0
- package/test/units/static/JBRulesets/JBRulesetsSetup.sol +21 -0
- package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +257 -0
- package/test/units/static/JBRulesets/TestCurrentOf.sol +231 -0
- package/test/units/static/JBRulesets/TestGetRulesetOf.sol +94 -0
- package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +252 -0
- package/test/units/static/JBRulesets/TestRulesets.sol +617 -0
- package/test/units/static/JBRulesets/TestRulesetsOf.sol +37 -0
- package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +526 -0
- package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +91 -0
- package/test/units/static/JBSplits/JBSplitsSetup.sol +23 -0
- package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +502 -0
- package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +370 -0
- package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +262 -0
- package/test/units/static/JBSplits/TestSplitsOf.sol +24 -0
- package/test/units/static/JBSplits/TestSplitsPacking.sol +33 -0
- package/test/units/static/JBSurplus/TestSurplusFuzz.sol +125 -0
- package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +23 -0
- package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +434 -0
- package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +428 -0
- package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +65 -0
- package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +479 -0
- package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +508 -0
- package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +257 -0
- package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +131 -0
- package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +390 -0
- package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +187 -0
- package/test/units/static/JBTokens/JBTokensSetup.sol +23 -0
- package/test/units/static/JBTokens/TestBurnFrom.sol +104 -0
- package/test/units/static/JBTokens/TestClaimTokensFor.sol +107 -0
- package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +89 -0
- package/test/units/static/JBTokens/TestMintFor.sol +97 -0
- package/test/units/static/JBTokens/TestSetTokenFor.sol +95 -0
- package/test/units/static/JBTokens/TestTotalBalanceOf.sol +65 -0
- package/test/units/static/JBTokens/TestTotalSupplyOf.sol +56 -0
- package/test/units/static/JBTokens/TestTransferCreditsFrom.sol +54 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import /* {*} from */ "../../../helpers/TestBaseWorkflow.sol";
|
|
5
|
+
import {JBTokensSetup} from "./JBTokensSetup.sol";
|
|
6
|
+
|
|
7
|
+
contract TestBurnFrom_Local is JBTokensSetup {
|
|
8
|
+
uint256 _projectId = 1;
|
|
9
|
+
uint256 _defaultAmount = 1e18;
|
|
10
|
+
|
|
11
|
+
// Mocks
|
|
12
|
+
IJBToken _token = IJBToken(makeAddr("token"));
|
|
13
|
+
|
|
14
|
+
function setUp() public {
|
|
15
|
+
super.tokensSetup();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
modifier whenCallerIsController() {
|
|
19
|
+
// mock call to JBDirectory controllerOf
|
|
20
|
+
mockExpect(
|
|
21
|
+
address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
_;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function test_GivenTheCallingAmountGTTokenbalancePlusCreditbalanceOfHolder() external whenCallerIsController {
|
|
28
|
+
// it will revert INSUFFICIENT_FUNDS
|
|
29
|
+
|
|
30
|
+
vm.expectRevert(abi.encodeWithSelector(JBTokens.JBTokens_InsufficientTokensToBurn.selector, _defaultAmount, 0));
|
|
31
|
+
_tokens.burnFrom(address(this), _projectId, _defaultAmount);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function test_GivenThereIsACreditBalance() external whenCallerIsController {
|
|
35
|
+
// it will subtract credits from creditBalanceOf and totalCreditSupplyOf
|
|
36
|
+
|
|
37
|
+
// Find the storage slot to set credit balance
|
|
38
|
+
bytes32 creditBalanceOfSlot = keccak256(abi.encode(address(this), uint256(0)));
|
|
39
|
+
bytes32 slot = keccak256(abi.encode(_projectId, uint256(creditBalanceOfSlot)));
|
|
40
|
+
|
|
41
|
+
// Set storage
|
|
42
|
+
vm.store(address(_tokens), slot, bytes32(_defaultAmount));
|
|
43
|
+
|
|
44
|
+
// Ensure it is correctly set
|
|
45
|
+
uint256 _creditBalance = _tokens.creditBalanceOf(address(this), _projectId);
|
|
46
|
+
assertEq(_defaultAmount, _creditBalance);
|
|
47
|
+
|
|
48
|
+
// Find the storage slot to set totalCreditSupplyOf
|
|
49
|
+
bytes32 totalCreditSlot = keccak256(abi.encode(_projectId, uint256(3)));
|
|
50
|
+
// Set storage
|
|
51
|
+
vm.store(address(_tokens), totalCreditSlot, bytes32(_defaultAmount));
|
|
52
|
+
|
|
53
|
+
// Ensure it is correctly set
|
|
54
|
+
uint256 _totalCreditSupply = _tokens.totalCreditSupplyOf(_projectId);
|
|
55
|
+
assertEq(_defaultAmount, _totalCreditSupply);
|
|
56
|
+
|
|
57
|
+
_tokens.burnFrom(address(this), _projectId, _defaultAmount);
|
|
58
|
+
|
|
59
|
+
// Ensure amount is zeroed now
|
|
60
|
+
uint256 _totalCreditSupplyAfter = _tokens.totalCreditSupplyOf(_projectId);
|
|
61
|
+
assertEq(0, _totalCreditSupplyAfter);
|
|
62
|
+
|
|
63
|
+
// Ensure it is correctly set
|
|
64
|
+
uint256 _creditBalanceAfter = _tokens.creditBalanceOf(address(this), _projectId);
|
|
65
|
+
assertEq(0, _creditBalanceAfter);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function test_GivenThereIsErc20TokenBalance() external whenCallerIsController {
|
|
69
|
+
// it will burn tokens
|
|
70
|
+
|
|
71
|
+
// Find the storage slot to set credit balance
|
|
72
|
+
bytes32 tokenOfSlot = keccak256(abi.encode(_projectId, uint256(2)));
|
|
73
|
+
|
|
74
|
+
// Set storage
|
|
75
|
+
vm.store(address(_tokens), tokenOfSlot, bytes32(uint256(uint160(address(_token)))));
|
|
76
|
+
|
|
77
|
+
// Ensure it's set
|
|
78
|
+
IJBToken _storedToken = _tokens.tokenOf(_projectId);
|
|
79
|
+
assertEq(address(_storedToken), address(_token));
|
|
80
|
+
|
|
81
|
+
// mock call to token balanceOf
|
|
82
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.balanceOf, (address(this))), abi.encode(_defaultAmount));
|
|
83
|
+
|
|
84
|
+
// mock call to token burn()
|
|
85
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.burn, (address(this), _defaultAmount)), "");
|
|
86
|
+
|
|
87
|
+
_tokens.burnFrom(address(this), _projectId, _defaultAmount);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function test_WhenCallerDNEQController() external {
|
|
91
|
+
// it will revert CONTROLLER_UNAUTHORIZED
|
|
92
|
+
|
|
93
|
+
// mock call that says zero address is controller of project
|
|
94
|
+
mockExpect(
|
|
95
|
+
address(directory),
|
|
96
|
+
abi.encodeCall(IJBDirectory.controllerOf, (_projectId)),
|
|
97
|
+
// will cause revert
|
|
98
|
+
abi.encode(address(0))
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
vm.expectRevert(abi.encodeWithSelector(JBControlled.JBControlled_ControllerUnauthorized.selector, address(0)));
|
|
102
|
+
_tokens.burnFrom(address(this), _projectId, _defaultAmount);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import /* {*} from */ "../../../helpers/TestBaseWorkflow.sol";
|
|
5
|
+
import {JBTokensSetup} from "./JBTokensSetup.sol";
|
|
6
|
+
|
|
7
|
+
contract TestClaimTokensFor_Local is JBTokensSetup {
|
|
8
|
+
uint256 _projectId = 1;
|
|
9
|
+
uint256 _defaultAmount = 1e18;
|
|
10
|
+
address _holder = address(this);
|
|
11
|
+
address _beneficiary = makeAddr("guy");
|
|
12
|
+
|
|
13
|
+
// Mocks
|
|
14
|
+
IJBToken _token = IJBToken(makeAddr("token"));
|
|
15
|
+
|
|
16
|
+
function setUp() public {
|
|
17
|
+
super.tokensSetup();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
modifier whenCallerIsController() {
|
|
21
|
+
// mock call to JBDirectory controllerOf
|
|
22
|
+
mockExpect(
|
|
23
|
+
address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
_;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function test_GivenTokenAddressEQZero() external whenCallerIsController {
|
|
30
|
+
// it will revert TOKEN_NOT_FOUND
|
|
31
|
+
|
|
32
|
+
// Find the storage slot to set credit balance
|
|
33
|
+
bytes32 tokenOfSlot = keccak256(abi.encode(_projectId, uint256(2)));
|
|
34
|
+
|
|
35
|
+
// Set storage
|
|
36
|
+
vm.store(address(_tokens), tokenOfSlot, bytes32(uint256(uint160(address(0)))));
|
|
37
|
+
|
|
38
|
+
vm.expectRevert(JBTokens.JBTokens_TokenNotFound.selector);
|
|
39
|
+
_tokens.claimTokensFor(_holder, _projectId, _defaultAmount, _beneficiary);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function test_GivenCreditBalanceOfGTCallingAmount() external whenCallerIsController {
|
|
43
|
+
// it will revert INSUFFICIENT_CREDITS
|
|
44
|
+
|
|
45
|
+
// Find the storage slot to set credit balance
|
|
46
|
+
bytes32 tokenOfSlot = keccak256(abi.encode(_projectId, uint256(2)));
|
|
47
|
+
|
|
48
|
+
// Set storage
|
|
49
|
+
vm.store(address(_tokens), tokenOfSlot, bytes32(uint256(uint160(address(_token)))));
|
|
50
|
+
|
|
51
|
+
vm.expectRevert(abi.encodeWithSelector(JBTokens.JBTokens_InsufficientCredits.selector, _defaultAmount, 0));
|
|
52
|
+
_tokens.claimTokensFor(_holder, _projectId, _defaultAmount, _beneficiary);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function test_GivenHappyPath() external whenCallerIsController {
|
|
56
|
+
// it will mint to the beneficiary and emit ClaimTokens
|
|
57
|
+
|
|
58
|
+
// Find the storage slot to set credit balance
|
|
59
|
+
bytes32 tokenOfSlot = keccak256(abi.encode(_projectId, uint256(2)));
|
|
60
|
+
|
|
61
|
+
// Set storage
|
|
62
|
+
vm.store(address(_tokens), tokenOfSlot, bytes32(uint256(uint160(address(_token)))));
|
|
63
|
+
|
|
64
|
+
// Find the storage slot to set credit balance
|
|
65
|
+
bytes32 creditBalanceOfSlot = keccak256(abi.encode(address(this), uint256(0)));
|
|
66
|
+
bytes32 slot = keccak256(abi.encode(_projectId, uint256(creditBalanceOfSlot)));
|
|
67
|
+
|
|
68
|
+
// Set storage
|
|
69
|
+
vm.store(address(_tokens), slot, bytes32(_defaultAmount));
|
|
70
|
+
|
|
71
|
+
// Ensure it is correctly set
|
|
72
|
+
uint256 _creditBalance = _tokens.creditBalanceOf(address(this), _projectId);
|
|
73
|
+
assertEq(_defaultAmount, _creditBalance);
|
|
74
|
+
|
|
75
|
+
// Find the storage slot to set totalCreditSupplyOf
|
|
76
|
+
bytes32 totalCreditSlot = keccak256(abi.encode(_projectId, uint256(3)));
|
|
77
|
+
// Set storage
|
|
78
|
+
vm.store(address(_tokens), totalCreditSlot, bytes32(_defaultAmount));
|
|
79
|
+
|
|
80
|
+
// Ensure it is correctly set
|
|
81
|
+
uint256 _totalCreditSupply = _tokens.totalCreditSupplyOf(_projectId);
|
|
82
|
+
assertEq(_defaultAmount, _totalCreditSupply);
|
|
83
|
+
|
|
84
|
+
// mock call to token mint()
|
|
85
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.mint, (_beneficiary, _defaultAmount)), "");
|
|
86
|
+
|
|
87
|
+
_tokens.claimTokensFor(_holder, _projectId, _defaultAmount, _beneficiary);
|
|
88
|
+
|
|
89
|
+
// Ensure amount is zeroed now
|
|
90
|
+
uint256 _totalCreditSupplyAfter = _tokens.totalCreditSupplyOf(_projectId);
|
|
91
|
+
assertEq(0, _totalCreditSupplyAfter);
|
|
92
|
+
|
|
93
|
+
// Ensure it is correctly set
|
|
94
|
+
uint256 _creditBalanceAfter = _tokens.creditBalanceOf(address(this), _projectId);
|
|
95
|
+
assertEq(0, _creditBalanceAfter);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function test_WhenCallerIsNotController() external {
|
|
99
|
+
// it will revert CONTROLLER_UNAUTHORIZED
|
|
100
|
+
|
|
101
|
+
// mock call to JBDirectory controllerOf
|
|
102
|
+
mockExpect(address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(0)));
|
|
103
|
+
|
|
104
|
+
vm.expectRevert(abi.encodeWithSelector(JBControlled.JBControlled_ControllerUnauthorized.selector, address(0)));
|
|
105
|
+
_tokens.claimTokensFor(_holder, _projectId, _defaultAmount, _beneficiary);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import /* {*} from */ "../../../helpers/TestBaseWorkflow.sol";
|
|
5
|
+
import {JBTokensSetup} from "./JBTokensSetup.sol";
|
|
6
|
+
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
|
|
7
|
+
|
|
8
|
+
contract TestDeployERC20ForUnits_Local is JBTokensSetup {
|
|
9
|
+
uint256 _projectId = 1;
|
|
10
|
+
string _name = "Juice";
|
|
11
|
+
string _symbol = "JBX";
|
|
12
|
+
IJBToken _token = IJBToken(makeAddr("JBX"));
|
|
13
|
+
|
|
14
|
+
function setUp() public {
|
|
15
|
+
super.tokensSetup();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
modifier whenCallerIsController() {
|
|
19
|
+
// mock call to JBDirectory controllerOf
|
|
20
|
+
mockExpect(
|
|
21
|
+
address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
_;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function test_WhenNameLengthEQZero() external whenCallerIsController {
|
|
28
|
+
// it will revert EMPTY_NAME
|
|
29
|
+
|
|
30
|
+
vm.expectRevert(JBTokens.JBTokens_EmptyName.selector);
|
|
31
|
+
_tokens.deployERC20For({projectId: _projectId, name: "", symbol: _symbol, salt: bytes32(0)});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function test_WhenSymbolLengthEQZero() external whenCallerIsController {
|
|
35
|
+
// it will revert EMPTY_SYMBOL
|
|
36
|
+
|
|
37
|
+
vm.expectRevert(JBTokens.JBTokens_EmptySymbol.selector);
|
|
38
|
+
_tokens.deployERC20For({projectId: _projectId, name: _name, symbol: "", salt: bytes32(0)});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function test_WhenProjectAlreadyHasAConfiguredToken() external whenCallerIsController {
|
|
42
|
+
// it will revert PROJECT_ALREADY_HAS_TOKEN
|
|
43
|
+
|
|
44
|
+
// Find the storage slot to set credit balance
|
|
45
|
+
bytes32 tokenOfSlot = keccak256(abi.encode(_projectId, uint256(2)));
|
|
46
|
+
|
|
47
|
+
// Set storage
|
|
48
|
+
vm.store(address(_tokens), tokenOfSlot, bytes32(uint256(uint160(address(_token)))));
|
|
49
|
+
|
|
50
|
+
// Ensure it's set
|
|
51
|
+
IJBToken _storedToken = _tokens.tokenOf(_projectId);
|
|
52
|
+
assertEq(address(_storedToken), address(_token));
|
|
53
|
+
|
|
54
|
+
vm.expectRevert(abi.encodeWithSelector(JBTokens.JBTokens_ProjectAlreadyHasToken.selector, _storedToken));
|
|
55
|
+
_tokens.deployERC20For({projectId: _projectId, name: _name, symbol: _symbol, salt: bytes32(0)});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
modifier whenHappyPath() {
|
|
59
|
+
_;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function test_GivenASaltIsProvided() external whenHappyPath whenCallerIsController {
|
|
63
|
+
// it will create and initialize a deterministic clone based on the msgsender and salt
|
|
64
|
+
|
|
65
|
+
bytes32 salt = bytes32(uint256(1));
|
|
66
|
+
bytes32 hashedSalt = keccak256(abi.encode(address(this), salt));
|
|
67
|
+
address deployer = address(_tokens);
|
|
68
|
+
address token = address(jbToken);
|
|
69
|
+
|
|
70
|
+
address predicted = Clones.predictDeterministicAddress(token, hashedSalt, deployer);
|
|
71
|
+
|
|
72
|
+
vm.expectEmit();
|
|
73
|
+
emit IJBTokens.DeployERC20(_projectId, IJBToken(predicted), _name, _symbol, salt, address(this));
|
|
74
|
+
|
|
75
|
+
IJBToken deployedToken =
|
|
76
|
+
_tokens.deployERC20For({projectId: _projectId, name: _name, symbol: _symbol, salt: salt});
|
|
77
|
+
|
|
78
|
+
assertEq(predicted, address(deployedToken));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function test_GivenASaltIsNotProvided() external whenHappyPath whenCallerIsController {
|
|
82
|
+
// it will clone and initialize a indeterministically generated clone
|
|
83
|
+
|
|
84
|
+
IJBToken deployedToken =
|
|
85
|
+
_tokens.deployERC20For({projectId: _projectId, name: _name, symbol: _symbol, salt: bytes32(0)});
|
|
86
|
+
|
|
87
|
+
if (address(deployedToken) == address(0)) revert();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import /* {*} from */ "../../../helpers/TestBaseWorkflow.sol";
|
|
5
|
+
import {JBTokensSetup} from "./JBTokensSetup.sol";
|
|
6
|
+
|
|
7
|
+
contract TestMintFor_Local is JBTokensSetup {
|
|
8
|
+
uint256 _projectId = 1;
|
|
9
|
+
uint256 _defaultAmount = 1e18;
|
|
10
|
+
uint256 _totalSupply = 1e19;
|
|
11
|
+
uint256 _overflowedSupply = uint256(type(uint208).max) + 1;
|
|
12
|
+
address _holder = address(this);
|
|
13
|
+
|
|
14
|
+
// Mocks
|
|
15
|
+
IJBToken _token = IJBToken(makeAddr("token"));
|
|
16
|
+
|
|
17
|
+
function setUp() public {
|
|
18
|
+
super.tokensSetup();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
modifier whenCallerIsControllerOfProject() {
|
|
22
|
+
// mock call to JBDirectory controllerOf
|
|
23
|
+
mockExpect(
|
|
24
|
+
address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
_;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function test_GivenTokenOfTheProjectEQZeroAddress() external whenCallerIsControllerOfProject {
|
|
31
|
+
// it will add tokens to credit balances and total credit supply
|
|
32
|
+
|
|
33
|
+
// Find the storage slot to set token
|
|
34
|
+
bytes32 tokenOfSlot = keccak256(abi.encode(_projectId, uint256(2)));
|
|
35
|
+
|
|
36
|
+
// Set storage
|
|
37
|
+
vm.store(address(_tokens), tokenOfSlot, bytes32(uint256(uint160(address(0)))));
|
|
38
|
+
|
|
39
|
+
_tokens.mintFor(_holder, _projectId, _defaultAmount);
|
|
40
|
+
|
|
41
|
+
// Ensure credit supply increase
|
|
42
|
+
uint256 _totalCreditSupplyAfter = _tokens.totalCreditSupplyOf(_projectId);
|
|
43
|
+
assertEq(_defaultAmount, _totalCreditSupplyAfter);
|
|
44
|
+
|
|
45
|
+
// Ensure credit balance increase
|
|
46
|
+
uint256 _creditBalanceAfter = _tokens.creditBalanceOf(address(this), _projectId);
|
|
47
|
+
assertEq(_defaultAmount, _creditBalanceAfter);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function test_GivenTokenDNEQZeroAddress() external whenCallerIsControllerOfProject {
|
|
51
|
+
// it will call token mint
|
|
52
|
+
|
|
53
|
+
// Find the storage slot to set token
|
|
54
|
+
bytes32 tokenOfSlot = keccak256(abi.encode(_projectId, uint256(2)));
|
|
55
|
+
|
|
56
|
+
// Set storage
|
|
57
|
+
vm.store(address(_tokens), tokenOfSlot, bytes32(uint256(uint160(address(_token)))));
|
|
58
|
+
|
|
59
|
+
// mock call to token mint()
|
|
60
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.mint, (_holder, _defaultAmount)), "");
|
|
61
|
+
|
|
62
|
+
// mock call to token totalSupply()
|
|
63
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.totalSupply, ()), abi.encode(_totalSupply));
|
|
64
|
+
|
|
65
|
+
_tokens.mintFor(_holder, _projectId, _defaultAmount);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function test_GivenTotalSupplyAfterMintOrCreditsGTUint208Max() external whenCallerIsControllerOfProject {
|
|
69
|
+
// it will revert OVERFLOW_ALERT
|
|
70
|
+
|
|
71
|
+
// Find the storage slot to set token
|
|
72
|
+
bytes32 tokenOfSlot = keccak256(abi.encode(_projectId, uint256(2)));
|
|
73
|
+
|
|
74
|
+
// Set storage
|
|
75
|
+
vm.store(address(_tokens), tokenOfSlot, bytes32(uint256(uint160(address(_token)))));
|
|
76
|
+
|
|
77
|
+
// mock call to token totalSupply() - overflow check happens before mint
|
|
78
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.totalSupply, ()), abi.encode(_overflowedSupply));
|
|
79
|
+
|
|
80
|
+
vm.expectRevert(
|
|
81
|
+
abi.encodeWithSelector(
|
|
82
|
+
JBTokens.JBTokens_OverflowAlert.selector, _overflowedSupply + _defaultAmount, type(uint208).max
|
|
83
|
+
)
|
|
84
|
+
);
|
|
85
|
+
_tokens.mintFor(_holder, _projectId, _defaultAmount);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function test_WhenCallerIsNotController() external {
|
|
89
|
+
// it will revert CONTROLLER_UNAUTHORIZED
|
|
90
|
+
|
|
91
|
+
// mock call to JBDirectory controllerOf
|
|
92
|
+
mockExpect(address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(0)));
|
|
93
|
+
|
|
94
|
+
vm.expectRevert(abi.encodeWithSelector(JBControlled.JBControlled_ControllerUnauthorized.selector, address(0)));
|
|
95
|
+
_tokens.mintFor(_holder, _projectId, _defaultAmount);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import /* {*} from */ "../../../helpers/TestBaseWorkflow.sol";
|
|
5
|
+
import {JBTokensSetup} from "./JBTokensSetup.sol";
|
|
6
|
+
|
|
7
|
+
contract TestSetTokenFor_Local is JBTokensSetup {
|
|
8
|
+
uint256 _projectId = 1;
|
|
9
|
+
|
|
10
|
+
// Mocks
|
|
11
|
+
IJBToken _token = IJBToken(makeAddr("token"));
|
|
12
|
+
|
|
13
|
+
function setUp() public {
|
|
14
|
+
super.tokensSetup();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
modifier whenCallerIsControllerOfProject() {
|
|
18
|
+
// mock call to JBDirectory controllerOf
|
|
19
|
+
mockExpect(
|
|
20
|
+
address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
_;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function test_WhenTokenIsTheZeroAddress() external whenCallerIsControllerOfProject {
|
|
27
|
+
// it will revert EMPTY_TOKEN
|
|
28
|
+
|
|
29
|
+
vm.expectRevert(abi.encodeWithSelector(JBTokens.JBTokens_EmptyToken.selector, _projectId));
|
|
30
|
+
_tokens.setTokenFor(_projectId, IJBToken(address(0)));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function test_WhenATokenIsAlreadySet() external whenCallerIsControllerOfProject {
|
|
34
|
+
// it will revert TOKEN_ALREADY_SET
|
|
35
|
+
|
|
36
|
+
// Find the storage slot to set token
|
|
37
|
+
bytes32 tokenOfSlot = keccak256(abi.encode(_projectId, uint256(2)));
|
|
38
|
+
|
|
39
|
+
// Set storage
|
|
40
|
+
vm.store(address(_tokens), tokenOfSlot, bytes32(uint256(uint160(address(_token)))));
|
|
41
|
+
|
|
42
|
+
vm.expectRevert(abi.encodeWithSelector(JBTokens.JBTokens_ProjectAlreadyHasToken.selector, _token));
|
|
43
|
+
_tokens.setTokenFor(_projectId, IJBToken(address(_token)));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function test_WhenATokenIsAssociatedWithAnotherProject() external whenCallerIsControllerOfProject {
|
|
47
|
+
// it will revert TOKEN_ALREADY_SET
|
|
48
|
+
|
|
49
|
+
// Find the storage slot to set token
|
|
50
|
+
bytes32 projectIdOfSlot = keccak256(abi.encode(_token, uint256(1)));
|
|
51
|
+
|
|
52
|
+
uint256 otherProjectId = 1234;
|
|
53
|
+
|
|
54
|
+
// Set storage
|
|
55
|
+
vm.store(address(_tokens), projectIdOfSlot, bytes32(uint256(otherProjectId)));
|
|
56
|
+
|
|
57
|
+
vm.expectRevert(abi.encodeWithSelector(JBTokens.JBTokens_TokenAlreadyBeingUsed.selector, otherProjectId));
|
|
58
|
+
_tokens.setTokenFor(_projectId, IJBToken(address(_token)));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function test_WhenATokensDecimalsDNEQ18() external whenCallerIsControllerOfProject {
|
|
62
|
+
// it will revert TOKENS_MUST_HAVE_18_DECIMALS
|
|
63
|
+
|
|
64
|
+
//mock call to token decimals
|
|
65
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.decimals, ()), abi.encode(6));
|
|
66
|
+
|
|
67
|
+
vm.expectRevert(abi.encodeWithSelector(JBTokens.JBTokens_TokensMustHave18Decimals.selector, 6));
|
|
68
|
+
_tokens.setTokenFor(_projectId, IJBToken(address(_token)));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function test_WhenHappyPath() external whenCallerIsControllerOfProject {
|
|
72
|
+
// it will set token states and emit SetToken
|
|
73
|
+
|
|
74
|
+
//mock call to token decimals
|
|
75
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.decimals, ()), abi.encode(18));
|
|
76
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.canBeAddedTo, (_projectId)), abi.encode(true));
|
|
77
|
+
|
|
78
|
+
vm.expectEmit();
|
|
79
|
+
emit IJBTokens.SetToken(_projectId, _token, address(this));
|
|
80
|
+
|
|
81
|
+
_tokens.setTokenFor(_projectId, IJBToken(address(_token)));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function test_WhenCantBeAddedTo() external whenCallerIsControllerOfProject {
|
|
85
|
+
// it will set token states and emit SetToken
|
|
86
|
+
|
|
87
|
+
//mock call to token decimals
|
|
88
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.decimals, ()), abi.encode(18));
|
|
89
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.canBeAddedTo, (_projectId)), abi.encode(false));
|
|
90
|
+
|
|
91
|
+
vm.expectRevert(abi.encodeWithSelector(JBTokens.JBTokens_TokenCantBeAdded.selector, _projectId));
|
|
92
|
+
|
|
93
|
+
_tokens.setTokenFor(_projectId, IJBToken(address(_token)));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import /* {*} from */ "../../../helpers/TestBaseWorkflow.sol";
|
|
5
|
+
import {JBTokensSetup} from "./JBTokensSetup.sol";
|
|
6
|
+
|
|
7
|
+
contract TestTotalBalanceOf_Local is JBTokensSetup {
|
|
8
|
+
address _holder = address(this);
|
|
9
|
+
uint256 _projectId = 1;
|
|
10
|
+
uint256 _creditBalance = 1e18;
|
|
11
|
+
uint256 _tokenBalance = 2e18;
|
|
12
|
+
|
|
13
|
+
// Mocks
|
|
14
|
+
IJBToken _token = IJBToken(makeAddr("token"));
|
|
15
|
+
|
|
16
|
+
function setUp() public {
|
|
17
|
+
super.tokensSetup();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function test_WhenAProjectsTokenDNEQZeroAddress() external {
|
|
21
|
+
// it will return creditBalanceOf plus token balance of holder
|
|
22
|
+
|
|
23
|
+
// Find the storage slot to set credit balance
|
|
24
|
+
bytes32 creditBalanceOfSlot = keccak256(abi.encode(address(this), uint256(0)));
|
|
25
|
+
bytes32 slot = keccak256(abi.encode(_projectId, uint256(creditBalanceOfSlot)));
|
|
26
|
+
|
|
27
|
+
// Set storage
|
|
28
|
+
vm.store(address(_tokens), slot, bytes32(_creditBalance));
|
|
29
|
+
|
|
30
|
+
// Find the storage slot to set token
|
|
31
|
+
bytes32 tokenOfSlot = keccak256(abi.encode(_projectId, uint256(2)));
|
|
32
|
+
|
|
33
|
+
// Set storage
|
|
34
|
+
vm.store(address(_tokens), tokenOfSlot, bytes32(uint256(uint160(address(_token)))));
|
|
35
|
+
|
|
36
|
+
// mock call to token balanceOf
|
|
37
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.balanceOf, (_holder)), abi.encode(_tokenBalance));
|
|
38
|
+
|
|
39
|
+
uint256 totalBalance = _tokens.totalBalanceOf(_holder, _projectId);
|
|
40
|
+
|
|
41
|
+
// Ensure correct balance
|
|
42
|
+
assertEq(totalBalance, _tokenBalance + _creditBalance);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function test_WhenAProjectsTokenEQZeroAddressAndCreditBalanceEQZero() external view {
|
|
46
|
+
// it will return zero
|
|
47
|
+
|
|
48
|
+
uint256 totalBalance = _tokens.totalBalanceOf(_holder, _projectId);
|
|
49
|
+
assertEq(totalBalance, 0);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function test_WhenThereIsOnlyCreditBalance() external {
|
|
53
|
+
// it will return only the credit balance
|
|
54
|
+
|
|
55
|
+
// Find the storage slot to set credit balance
|
|
56
|
+
bytes32 creditBalanceOfSlot = keccak256(abi.encode(address(this), uint256(0)));
|
|
57
|
+
bytes32 slot = keccak256(abi.encode(_projectId, uint256(creditBalanceOfSlot)));
|
|
58
|
+
|
|
59
|
+
// Set storage
|
|
60
|
+
vm.store(address(_tokens), slot, bytes32(_creditBalance));
|
|
61
|
+
|
|
62
|
+
uint256 totalBalance = _tokens.totalBalanceOf(_holder, _projectId);
|
|
63
|
+
assertEq(totalBalance, _creditBalance);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import /* {*} from */ "../../../helpers/TestBaseWorkflow.sol";
|
|
5
|
+
import {JBTokensSetup} from "./JBTokensSetup.sol";
|
|
6
|
+
|
|
7
|
+
contract TestTotalSupplyOf_Local is JBTokensSetup {
|
|
8
|
+
uint256 _projectId = 1;
|
|
9
|
+
uint256 _defaultAmount = 1e18;
|
|
10
|
+
|
|
11
|
+
// Mocks
|
|
12
|
+
IJBToken _token = IJBToken(makeAddr("token"));
|
|
13
|
+
|
|
14
|
+
function setUp() public {
|
|
15
|
+
super.tokensSetup();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function test_WhenAProjectsTokenDNEQZeroAddress() external {
|
|
19
|
+
// it will return totalCreditSupplyOf plus token total supply
|
|
20
|
+
|
|
21
|
+
// Find the storage slot to set totalCreditSupplyOf
|
|
22
|
+
bytes32 totalCreditSlot = keccak256(abi.encode(_projectId, uint256(3)));
|
|
23
|
+
// Set storage
|
|
24
|
+
vm.store(address(_tokens), totalCreditSlot, bytes32(_defaultAmount));
|
|
25
|
+
|
|
26
|
+
uint256 supply = _tokens.totalSupplyOf(_projectId);
|
|
27
|
+
assertEq(supply, _defaultAmount);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function test_WhenATokenIsConfigured() external {
|
|
31
|
+
// it will return totalCreditSupply + total token supply
|
|
32
|
+
|
|
33
|
+
// Find the storage slot to set totalCreditSupplyOf
|
|
34
|
+
bytes32 totalCreditSlot = keccak256(abi.encode(_projectId, uint256(3)));
|
|
35
|
+
// Set storage
|
|
36
|
+
vm.store(address(_tokens), totalCreditSlot, bytes32(_defaultAmount));
|
|
37
|
+
|
|
38
|
+
// Find the storage slot to set totalCreditSupplyOf
|
|
39
|
+
bytes32 tokenOfSlot = keccak256(abi.encode(_projectId, uint256(2)));
|
|
40
|
+
// Set storage
|
|
41
|
+
vm.store(address(_tokens), tokenOfSlot, bytes32(uint256(uint160(address(_token)))));
|
|
42
|
+
|
|
43
|
+
// mock call to token totalSupply()
|
|
44
|
+
mockExpect(address(_token), abi.encodeCall(IJBToken.totalSupply, ()), abi.encode(_defaultAmount));
|
|
45
|
+
|
|
46
|
+
uint256 supply = _tokens.totalSupplyOf(_projectId);
|
|
47
|
+
assertEq(supply, _defaultAmount * 2);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function test_WhenAProjectsTokenEQZeroAddressAndNoCreditSupply() external view {
|
|
51
|
+
// it will return zero
|
|
52
|
+
|
|
53
|
+
uint256 zeroSupply = _tokens.totalSupplyOf(_projectId);
|
|
54
|
+
assertEq(zeroSupply, 0);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import /* {*} from */ "../../../helpers/TestBaseWorkflow.sol";
|
|
5
|
+
import {JBTokensSetup} from "./JBTokensSetup.sol";
|
|
6
|
+
|
|
7
|
+
contract TestTransferCreditsFrom_Local is JBTokensSetup {
|
|
8
|
+
address _holder = address(this);
|
|
9
|
+
uint256 _projectId = 1;
|
|
10
|
+
address _recipient = makeAddr("guy");
|
|
11
|
+
uint256 _defaultAmount = 1e18;
|
|
12
|
+
|
|
13
|
+
function setUp() public {
|
|
14
|
+
super.tokensSetup();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
modifier whenCallerIsController() {
|
|
18
|
+
// mock call to JBDirectory controllerOf
|
|
19
|
+
mockExpect(
|
|
20
|
+
address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
_;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function test_GivenCallingAmountGTCreditBalance() external whenCallerIsController {
|
|
27
|
+
// it will revert INSUFFICIENT_CREDITS
|
|
28
|
+
|
|
29
|
+
vm.expectRevert(abi.encodeWithSelector(JBTokens.JBTokens_InsufficientCredits.selector, _defaultAmount, 0));
|
|
30
|
+
_tokens.transferCreditsFrom(_holder, _projectId, _recipient, _defaultAmount);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function test_GivenHappyPath() external whenCallerIsController {
|
|
34
|
+
// it will subtract creditBalanceOf from holder to recipient and emit TransferCredits
|
|
35
|
+
|
|
36
|
+
// Find the storage slot to set credit balance
|
|
37
|
+
bytes32 creditBalanceOfSlot = keccak256(abi.encode(_holder, uint256(0)));
|
|
38
|
+
bytes32 slot = keccak256(abi.encode(_projectId, uint256(creditBalanceOfSlot)));
|
|
39
|
+
|
|
40
|
+
// Set storage
|
|
41
|
+
vm.store(address(_tokens), slot, bytes32(_defaultAmount));
|
|
42
|
+
|
|
43
|
+
// Ensure it is correctly set
|
|
44
|
+
uint256 _creditBalance = _tokens.creditBalanceOf(address(this), _projectId);
|
|
45
|
+
assertEq(_defaultAmount, _creditBalance);
|
|
46
|
+
|
|
47
|
+
vm.expectEmit();
|
|
48
|
+
emit IJBTokens.TransferCredits(_holder, _projectId, _recipient, _defaultAmount, _holder);
|
|
49
|
+
|
|
50
|
+
_tokens.transferCreditsFrom(_holder, _projectId, _recipient, _defaultAmount);
|
|
51
|
+
uint256 recipientBalance = _tokens.creditBalanceOf(_recipient, _projectId);
|
|
52
|
+
assertEq(recipientBalance, _defaultAmount);
|
|
53
|
+
}
|
|
54
|
+
}
|