@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,908 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import {mulDiv} from "@prb/math/src/Common.sol";
|
|
5
|
+
|
|
6
|
+
import {IJBController} from "./interfaces/IJBController.sol";
|
|
7
|
+
import {IJBDirectory} from "./interfaces/IJBDirectory.sol";
|
|
8
|
+
import {IJBPrices} from "./interfaces/IJBPrices.sol";
|
|
9
|
+
import {IJBRulesetDataHook} from "./interfaces/IJBRulesetDataHook.sol";
|
|
10
|
+
import {IJBRulesets} from "./interfaces/IJBRulesets.sol";
|
|
11
|
+
import {IJBTerminal} from "./interfaces/IJBTerminal.sol";
|
|
12
|
+
import {IJBTerminalStore} from "./interfaces/IJBTerminalStore.sol";
|
|
13
|
+
import {JBFixedPointNumber} from "./libraries/JBFixedPointNumber.sol";
|
|
14
|
+
import {JBCashOuts} from "./libraries/JBCashOuts.sol";
|
|
15
|
+
import {JBRulesetMetadataResolver} from "./libraries/JBRulesetMetadataResolver.sol";
|
|
16
|
+
import {JBSurplus} from "./libraries/JBSurplus.sol";
|
|
17
|
+
import {JBAccountingContext} from "./structs/JBAccountingContext.sol";
|
|
18
|
+
import {JBBeforePayRecordedContext} from "./structs/JBBeforePayRecordedContext.sol";
|
|
19
|
+
import {JBBeforeCashOutRecordedContext} from "./structs/JBBeforeCashOutRecordedContext.sol";
|
|
20
|
+
import {JBCashOutHookSpecification} from "./structs/JBCashOutHookSpecification.sol";
|
|
21
|
+
import {JBCurrencyAmount} from "./structs/JBCurrencyAmount.sol";
|
|
22
|
+
import {JBPayHookSpecification} from "./structs/JBPayHookSpecification.sol";
|
|
23
|
+
import {JBRuleset} from "./structs/JBRuleset.sol";
|
|
24
|
+
import {JBTokenAmount} from "./structs/JBTokenAmount.sol";
|
|
25
|
+
|
|
26
|
+
/// @notice Manages all bookkeeping for inflows and outflows of funds from any terminal address.
|
|
27
|
+
/// @dev This contract expects a project's controller to be an `IJBController`.
|
|
28
|
+
contract JBTerminalStore is IJBTerminalStore {
|
|
29
|
+
// A library that parses the packed ruleset metadata into a friendlier format.
|
|
30
|
+
using JBRulesetMetadataResolver for JBRuleset;
|
|
31
|
+
|
|
32
|
+
//*********************************************************************//
|
|
33
|
+
// --------------------------- custom errors ------------------------- //
|
|
34
|
+
//*********************************************************************//
|
|
35
|
+
|
|
36
|
+
error JBTerminalStore_InadequateControllerAllowance(uint256 amount, uint256 allowance);
|
|
37
|
+
error JBTerminalStore_InadequateControllerPayoutLimit(uint256 amount, uint256 limit);
|
|
38
|
+
error JBTerminalStore_InadequateTerminalStoreBalance(uint256 amount, uint256 balance);
|
|
39
|
+
error JBTerminalStore_InsufficientTokens(uint256 count, uint256 totalSupply);
|
|
40
|
+
error JBTerminalStore_InvalidAmountToForwardHook(uint256 amount, uint256 paidAmount);
|
|
41
|
+
error JBTerminalStore_RulesetNotFound(uint256 projectId);
|
|
42
|
+
error JBTerminalStore_RulesetPaymentPaused();
|
|
43
|
+
error JBTerminalStore_TerminalMigrationNotAllowed();
|
|
44
|
+
error JBTerminalStore_Uint224Overflow(uint256 value);
|
|
45
|
+
|
|
46
|
+
//*********************************************************************//
|
|
47
|
+
// -------------------------- internal constants --------------------- //
|
|
48
|
+
//*********************************************************************//
|
|
49
|
+
|
|
50
|
+
/// @notice Constrains `mulDiv` operations on fixed point numbers to a maximum number of decimal points of persisted
|
|
51
|
+
/// fidelity.
|
|
52
|
+
uint256 internal constant _MAX_FIXED_POINT_FIDELITY = 18;
|
|
53
|
+
|
|
54
|
+
//*********************************************************************//
|
|
55
|
+
// ---------------- public immutable stored properties --------------- //
|
|
56
|
+
//*********************************************************************//
|
|
57
|
+
|
|
58
|
+
/// @notice The directory of terminals and controllers for projects.
|
|
59
|
+
IJBDirectory public immutable override DIRECTORY;
|
|
60
|
+
|
|
61
|
+
/// @notice The contract that exposes price feeds.
|
|
62
|
+
IJBPrices public immutable override PRICES;
|
|
63
|
+
|
|
64
|
+
/// @notice The contract storing and managing project rulesets.
|
|
65
|
+
IJBRulesets public immutable override RULESETS;
|
|
66
|
+
|
|
67
|
+
//*********************************************************************//
|
|
68
|
+
// --------------------- public stored properties -------------------- //
|
|
69
|
+
//*********************************************************************//
|
|
70
|
+
|
|
71
|
+
/// @notice A project's balance of a specific token within a terminal.
|
|
72
|
+
/// @dev The balance is represented as a fixed point number with the same amount of decimals as its relative
|
|
73
|
+
/// terminal.
|
|
74
|
+
/// @custom:param terminal The terminal to get the project's balance within.
|
|
75
|
+
/// @custom:param projectId The ID of the project to get the balance of.
|
|
76
|
+
/// @custom:param token The token to get the balance for.
|
|
77
|
+
mapping(address terminal => mapping(uint256 projectId => mapping(address token => uint256)))
|
|
78
|
+
public
|
|
79
|
+
override balanceOf;
|
|
80
|
+
|
|
81
|
+
/// @notice The currency-denominated amount of funds that a project has already paid out from its payout limit
|
|
82
|
+
/// during the current ruleset for each terminal, in terms of the payout limit's currency.
|
|
83
|
+
/// @dev Increases as projects pay out funds.
|
|
84
|
+
/// @dev The used payout limit is represented as a fixed point number with the same amount of decimals as the
|
|
85
|
+
/// terminal it applies to.
|
|
86
|
+
/// @custom:param terminal The terminal the payout limit applies to.
|
|
87
|
+
/// @custom:param projectId The ID of the project to get the used payout limit of.
|
|
88
|
+
/// @custom:param token The token the payout limit applies to in the terminal.
|
|
89
|
+
/// @custom:param rulesetCycleNumber The cycle number of the ruleset the payout limit was used during.
|
|
90
|
+
/// @custom:param currency The currency the payout limit is in terms of.
|
|
91
|
+
mapping(
|
|
92
|
+
address terminal
|
|
93
|
+
=> mapping(
|
|
94
|
+
uint256 projectId
|
|
95
|
+
=> mapping(address token => mapping(uint256 rulesetCycleNumber => mapping(uint256 currency => uint256)))
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
public
|
|
99
|
+
override usedPayoutLimitOf;
|
|
100
|
+
|
|
101
|
+
/// @notice The currency-denominated amounts of funds that a project has used from its surplus allowance during the
|
|
102
|
+
/// current ruleset for each terminal, in terms of the surplus allowance's currency.
|
|
103
|
+
/// @dev Increases as projects use their allowance.
|
|
104
|
+
/// @dev The used surplus allowance is represented as a fixed point number with the same amount of decimals as the
|
|
105
|
+
/// terminal it applies to.
|
|
106
|
+
/// @custom:param terminal The terminal the surplus allowance applies to.
|
|
107
|
+
/// @custom:param projectId The ID of the project to get the used surplus allowance of.
|
|
108
|
+
/// @custom:param token The token the surplus allowance applies to in the terminal.
|
|
109
|
+
/// @custom:param rulesetId The ID of the ruleset the surplus allowance was used during.
|
|
110
|
+
/// @custom:param currency The currency the surplus allowance is in terms of.
|
|
111
|
+
mapping(
|
|
112
|
+
address terminal
|
|
113
|
+
=> mapping(
|
|
114
|
+
uint256 projectId
|
|
115
|
+
=> mapping(address token => mapping(uint256 rulesetId => mapping(uint256 currency => uint256)))
|
|
116
|
+
)
|
|
117
|
+
)
|
|
118
|
+
public
|
|
119
|
+
override usedSurplusAllowanceOf;
|
|
120
|
+
|
|
121
|
+
//*********************************************************************//
|
|
122
|
+
// -------------------------- constructor ---------------------------- //
|
|
123
|
+
//*********************************************************************//
|
|
124
|
+
|
|
125
|
+
/// @param directory A contract storing directories of terminals and controllers for each project.
|
|
126
|
+
/// @param prices A contract that exposes price feeds.
|
|
127
|
+
/// @param rulesets A contract storing and managing project rulesets.
|
|
128
|
+
constructor(IJBDirectory directory, IJBPrices prices, IJBRulesets rulesets) {
|
|
129
|
+
DIRECTORY = directory;
|
|
130
|
+
PRICES = prices;
|
|
131
|
+
RULESETS = rulesets;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
//*********************************************************************//
|
|
135
|
+
// ------------------------- external views -------------------------- //
|
|
136
|
+
//*********************************************************************//
|
|
137
|
+
|
|
138
|
+
/// @notice Returns the number of surplus terminal tokens that would be reclaimed by cashing out a given project's
|
|
139
|
+
/// tokens based on its current ruleset and the given total project token supply and total terminal token surplus.
|
|
140
|
+
/// @param projectId The ID of the project whose project tokens would be cashed out.
|
|
141
|
+
/// @param cashOutCount The number of project tokens that would be cashed out, as a fixed point number with 18
|
|
142
|
+
/// decimals.
|
|
143
|
+
/// @param totalSupply The total project token supply, as a fixed point number with 18 decimals.
|
|
144
|
+
/// @param surplus The total terminal token surplus amount, as a fixed point number.
|
|
145
|
+
/// @return The number of surplus terminal tokens that would be reclaimed, as a fixed point number with the same
|
|
146
|
+
/// number of decimals as the provided `surplus`.
|
|
147
|
+
function currentReclaimableSurplusOf(
|
|
148
|
+
uint256 projectId,
|
|
149
|
+
uint256 cashOutCount,
|
|
150
|
+
uint256 totalSupply,
|
|
151
|
+
uint256 surplus
|
|
152
|
+
)
|
|
153
|
+
external
|
|
154
|
+
view
|
|
155
|
+
override
|
|
156
|
+
returns (uint256)
|
|
157
|
+
{
|
|
158
|
+
// If there's no surplus, nothing can be reclaimed.
|
|
159
|
+
if (surplus == 0) return 0;
|
|
160
|
+
|
|
161
|
+
// Can't cash out more tokens than are in the total supply.
|
|
162
|
+
if (cashOutCount > totalSupply) return 0;
|
|
163
|
+
|
|
164
|
+
// Get a reference to the project's current ruleset.
|
|
165
|
+
JBRuleset memory ruleset = RULESETS.currentOf(projectId);
|
|
166
|
+
|
|
167
|
+
// Return the amount of surplus terminal tokens that would be reclaimed.
|
|
168
|
+
return JBCashOuts.cashOutFrom({
|
|
169
|
+
surplus: surplus,
|
|
170
|
+
cashOutCount: cashOutCount,
|
|
171
|
+
totalSupply: totalSupply,
|
|
172
|
+
cashOutTaxRate: ruleset.cashOutTaxRate()
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/// @notice Returns the number of surplus terminal tokens that would be reclaimed from a terminal by cashing out a
|
|
177
|
+
/// given number of tokens, based on the total token supply and total surplus.
|
|
178
|
+
/// @dev The returned amount in terms of the specified `terminal`'s base currency.
|
|
179
|
+
/// @dev The returned amount is represented as a fixed point number with the same amount of decimals as the
|
|
180
|
+
/// specified terminal.
|
|
181
|
+
/// @param projectId The ID of the project whose tokens would be cashed out.
|
|
182
|
+
/// @param cashOutCount The number of tokens that would be cashed out, as a fixed point number with 18 decimals.
|
|
183
|
+
/// @param terminals The terminals that would be cashed out from. If this is an empty array, surplus within all
|
|
184
|
+
/// the project's terminals are considered.
|
|
185
|
+
/// @param accountingContexts The accounting contexts of the surplus terminal tokens that would be reclaimed. Pass
|
|
186
|
+
/// an empty array to use all of the project's accounting contexts.
|
|
187
|
+
/// @param decimals The number of decimals to include in the resulting fixed point number.
|
|
188
|
+
/// @param currency The currency that the resulting number will be in terms of.
|
|
189
|
+
/// @return The amount of surplus terminal tokens that would be reclaimed by cashing out `cashOutCount`
|
|
190
|
+
/// tokens.
|
|
191
|
+
function currentReclaimableSurplusOf(
|
|
192
|
+
uint256 projectId,
|
|
193
|
+
uint256 cashOutCount,
|
|
194
|
+
IJBTerminal[] calldata terminals,
|
|
195
|
+
JBAccountingContext[] calldata accountingContexts,
|
|
196
|
+
uint256 decimals,
|
|
197
|
+
uint256 currency
|
|
198
|
+
)
|
|
199
|
+
external
|
|
200
|
+
view
|
|
201
|
+
override
|
|
202
|
+
returns (uint256)
|
|
203
|
+
{
|
|
204
|
+
// Get a reference to the project's current ruleset.
|
|
205
|
+
JBRuleset memory ruleset = RULESETS.currentOf(projectId);
|
|
206
|
+
|
|
207
|
+
// Get the current surplus amount.
|
|
208
|
+
// If a terminal wasn't provided, use the total surplus across all terminals. Otherwise,
|
|
209
|
+
// get the `terminal`'s surplus.
|
|
210
|
+
uint256 currentSurplus = JBSurplus.currentSurplusOf({
|
|
211
|
+
projectId: projectId,
|
|
212
|
+
terminals: terminals.length != 0 ? terminals : DIRECTORY.terminalsOf(projectId),
|
|
213
|
+
accountingContexts: accountingContexts,
|
|
214
|
+
decimals: decimals,
|
|
215
|
+
currency: currency
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// If there's no surplus, nothing can be reclaimed.
|
|
219
|
+
if (currentSurplus == 0) return 0;
|
|
220
|
+
|
|
221
|
+
// Get the project token's total supply.
|
|
222
|
+
uint256 totalSupply =
|
|
223
|
+
IJBController(address(DIRECTORY.controllerOf(projectId))).totalTokenSupplyWithReservedTokensOf(projectId);
|
|
224
|
+
|
|
225
|
+
// Can't cash out more tokens than are in the total supply.
|
|
226
|
+
if (cashOutCount > totalSupply) return 0;
|
|
227
|
+
|
|
228
|
+
// Return the amount of surplus terminal tokens that would be reclaimed.
|
|
229
|
+
return JBCashOuts.cashOutFrom({
|
|
230
|
+
surplus: currentSurplus,
|
|
231
|
+
cashOutCount: cashOutCount,
|
|
232
|
+
totalSupply: totalSupply,
|
|
233
|
+
cashOutTaxRate: ruleset.cashOutTaxRate()
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/// @notice Gets the current surplus amount in a terminal for a specified project.
|
|
238
|
+
/// @dev The surplus is the amount of funds a project has in a terminal in excess of its payout limit.
|
|
239
|
+
/// @dev The surplus is represented as a fixed point number with the same amount of decimals as the specified
|
|
240
|
+
/// terminal.
|
|
241
|
+
/// @param terminal The terminal the surplus is being calculated for.
|
|
242
|
+
/// @param projectId The ID of the project to get surplus for.
|
|
243
|
+
/// @param accountingContexts The accounting contexts of tokens whose balances should contribute to the surplus
|
|
244
|
+
/// being calculated.
|
|
245
|
+
/// @param currency The currency the resulting amount should be in terms of.
|
|
246
|
+
/// @param decimals The number of decimals to expect in the resulting fixed point number.
|
|
247
|
+
/// @return The current surplus amount the project has in the specified terminal.
|
|
248
|
+
function currentSurplusOf(
|
|
249
|
+
address terminal,
|
|
250
|
+
uint256 projectId,
|
|
251
|
+
JBAccountingContext[] calldata accountingContexts,
|
|
252
|
+
uint256 decimals,
|
|
253
|
+
uint256 currency
|
|
254
|
+
)
|
|
255
|
+
external
|
|
256
|
+
view
|
|
257
|
+
override
|
|
258
|
+
returns (uint256)
|
|
259
|
+
{
|
|
260
|
+
// Return the surplus during the project's current ruleset.
|
|
261
|
+
return _surplusFrom({
|
|
262
|
+
terminal: terminal,
|
|
263
|
+
projectId: projectId,
|
|
264
|
+
accountingContexts: accountingContexts,
|
|
265
|
+
ruleset: RULESETS.currentOf(projectId),
|
|
266
|
+
targetDecimals: decimals,
|
|
267
|
+
targetCurrency: currency
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/// @notice Gets the current surplus amount for a specified project across all terminals.
|
|
272
|
+
/// @param projectId The ID of the project to get the total surplus for.
|
|
273
|
+
/// @param decimals The number of decimals that the fixed point surplus should include.
|
|
274
|
+
/// @param currency The currency that the total surplus should be in terms of.
|
|
275
|
+
/// @return The current total surplus amount that the project has across all terminals.
|
|
276
|
+
function currentTotalSurplusOf(
|
|
277
|
+
uint256 projectId,
|
|
278
|
+
uint256 decimals,
|
|
279
|
+
uint256 currency
|
|
280
|
+
)
|
|
281
|
+
external
|
|
282
|
+
view
|
|
283
|
+
override
|
|
284
|
+
returns (uint256)
|
|
285
|
+
{
|
|
286
|
+
return JBSurplus.currentSurplusOf({
|
|
287
|
+
projectId: projectId,
|
|
288
|
+
terminals: DIRECTORY.terminalsOf(projectId),
|
|
289
|
+
accountingContexts: new JBAccountingContext[](0),
|
|
290
|
+
decimals: decimals,
|
|
291
|
+
currency: currency
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
//*********************************************************************//
|
|
296
|
+
// -------------------------- internal views ------------------------- //
|
|
297
|
+
//*********************************************************************//
|
|
298
|
+
|
|
299
|
+
/// @notice Gets a project's surplus amount in a terminal as measured by a given ruleset, across multiple accounting
|
|
300
|
+
/// contexts.
|
|
301
|
+
/// @dev This amount changes as the value of the balance changes in relation to the currency being used to measure
|
|
302
|
+
/// various payout limits.
|
|
303
|
+
/// @param terminal The terminal the surplus is being calculated for.
|
|
304
|
+
/// @param projectId The ID of the project to get the surplus for.
|
|
305
|
+
/// @param accountingContexts The accounting contexts of tokens whose balances should contribute to the surplus
|
|
306
|
+
/// being calculated.
|
|
307
|
+
/// @param ruleset The ID of the ruleset to base the surplus on.
|
|
308
|
+
/// @param targetDecimals The number of decimals to include in the resulting fixed point number.
|
|
309
|
+
/// @param targetCurrency The currency that the reported surplus is expected to be in terms of.
|
|
310
|
+
/// @return surplus The surplus of funds in terms of `targetCurrency`, as a fixed point number with
|
|
311
|
+
/// `targetDecimals` decimals.
|
|
312
|
+
function _surplusFrom(
|
|
313
|
+
address terminal,
|
|
314
|
+
uint256 projectId,
|
|
315
|
+
JBAccountingContext[] memory accountingContexts,
|
|
316
|
+
JBRuleset memory ruleset,
|
|
317
|
+
uint256 targetDecimals,
|
|
318
|
+
uint256 targetCurrency
|
|
319
|
+
)
|
|
320
|
+
internal
|
|
321
|
+
view
|
|
322
|
+
returns (uint256 surplus)
|
|
323
|
+
{
|
|
324
|
+
// Keep a reference to the number of tokens being iterated on.
|
|
325
|
+
uint256 numberOfTokenAccountingContexts = accountingContexts.length;
|
|
326
|
+
|
|
327
|
+
// Add payout limits from each token.
|
|
328
|
+
for (uint256 i; i < numberOfTokenAccountingContexts; i++) {
|
|
329
|
+
uint256 tokenSurplus = _tokenSurplusFrom({
|
|
330
|
+
terminal: terminal,
|
|
331
|
+
projectId: projectId,
|
|
332
|
+
accountingContext: accountingContexts[i],
|
|
333
|
+
ruleset: ruleset,
|
|
334
|
+
targetDecimals: targetDecimals,
|
|
335
|
+
targetCurrency: targetCurrency
|
|
336
|
+
});
|
|
337
|
+
// Increment the surplus with any remaining balance.
|
|
338
|
+
if (tokenSurplus > 0) surplus += tokenSurplus;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/// @notice Get a project's surplus amount of a specific token in a given terminal as measured by a given ruleset
|
|
343
|
+
/// (one specific accounting context).
|
|
344
|
+
/// @dev This amount changes as the value of the balance changes in relation to the currency being used to measure
|
|
345
|
+
/// the payout limits.
|
|
346
|
+
/// @param terminal The terminal the surplus is being calculated for.
|
|
347
|
+
/// @param projectId The ID of the project to get the surplus of.
|
|
348
|
+
/// @param accountingContext The accounting context of the token whose balance should contribute to the surplus
|
|
349
|
+
/// being measured.
|
|
350
|
+
/// @param ruleset The ID of the ruleset to base the surplus calculation on.
|
|
351
|
+
/// @param targetDecimals The number of decimals to include in the resulting fixed point number.
|
|
352
|
+
/// @param targetCurrency The currency that the reported surplus is expected to be in terms of.
|
|
353
|
+
/// @return surplus The surplus of funds in terms of `targetCurrency`, as a fixed point number with
|
|
354
|
+
/// `targetDecimals` decimals.
|
|
355
|
+
function _tokenSurplusFrom(
|
|
356
|
+
address terminal,
|
|
357
|
+
uint256 projectId,
|
|
358
|
+
JBAccountingContext memory accountingContext,
|
|
359
|
+
JBRuleset memory ruleset,
|
|
360
|
+
uint256 targetDecimals,
|
|
361
|
+
uint256 targetCurrency
|
|
362
|
+
)
|
|
363
|
+
internal
|
|
364
|
+
view
|
|
365
|
+
returns (uint256 surplus)
|
|
366
|
+
{
|
|
367
|
+
// Keep a reference to the balance.
|
|
368
|
+
surplus = balanceOf[terminal][projectId][accountingContext.token];
|
|
369
|
+
|
|
370
|
+
// If needed, adjust the decimals of the fixed point number to have the correct decimals.
|
|
371
|
+
surplus = accountingContext.decimals == targetDecimals
|
|
372
|
+
? surplus
|
|
373
|
+
: JBFixedPointNumber.adjustDecimals({
|
|
374
|
+
value: surplus, decimals: accountingContext.decimals, targetDecimals: targetDecimals
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
// Add up all the balances.
|
|
378
|
+
surplus = (surplus == 0 || accountingContext.currency == targetCurrency)
|
|
379
|
+
? surplus
|
|
380
|
+
: mulDiv(
|
|
381
|
+
surplus,
|
|
382
|
+
10 ** _MAX_FIXED_POINT_FIDELITY, // Use `_MAX_FIXED_POINT_FIDELITY` to keep as much of the
|
|
383
|
+
// `_payoutLimitRemaining`'s fidelity as possible when converting.
|
|
384
|
+
PRICES.pricePerUnitOf({
|
|
385
|
+
projectId: projectId,
|
|
386
|
+
pricingCurrency: accountingContext.currency,
|
|
387
|
+
unitCurrency: targetCurrency,
|
|
388
|
+
decimals: _MAX_FIXED_POINT_FIDELITY
|
|
389
|
+
})
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
// Get a reference to the payout limit during the ruleset for the token.
|
|
393
|
+
JBCurrencyAmount[] memory payoutLimits = IJBController(address(DIRECTORY.controllerOf(projectId)))
|
|
394
|
+
.FUND_ACCESS_LIMITS()
|
|
395
|
+
.payoutLimitsOf({
|
|
396
|
+
projectId: projectId, rulesetId: ruleset.id, terminal: address(terminal), token: accountingContext.token
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// Keep a reference to the number of payout limits being iterated on.
|
|
400
|
+
uint256 numberOfPayoutLimits = payoutLimits.length;
|
|
401
|
+
|
|
402
|
+
// Loop through each payout limit to determine the cumulative normalized payout limit remaining.
|
|
403
|
+
for (uint256 i; i < numberOfPayoutLimits; i++) {
|
|
404
|
+
JBCurrencyAmount memory payoutLimit = payoutLimits[i];
|
|
405
|
+
|
|
406
|
+
// Set the payout limit value to the amount still available to pay out during the ruleset.
|
|
407
|
+
{
|
|
408
|
+
uint256 remaining = payoutLimit.amount
|
|
409
|
+
- usedPayoutLimitOf[
|
|
410
|
+
terminal
|
|
411
|
+
][projectId][accountingContext.token][ruleset.cycleNumber][payoutLimit.currency];
|
|
412
|
+
if (remaining > type(uint224).max) revert JBTerminalStore_Uint224Overflow(remaining);
|
|
413
|
+
payoutLimit.amount = uint224(remaining);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Adjust the decimals of the fixed point number if needed to have the correct decimals.
|
|
417
|
+
if (accountingContext.decimals != targetDecimals) {
|
|
418
|
+
uint256 adjusted = JBFixedPointNumber.adjustDecimals({
|
|
419
|
+
value: payoutLimit.amount, decimals: accountingContext.decimals, targetDecimals: targetDecimals
|
|
420
|
+
});
|
|
421
|
+
if (adjusted > type(uint224).max) revert JBTerminalStore_Uint224Overflow(adjusted);
|
|
422
|
+
payoutLimit.amount = uint224(adjusted);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Convert the `payoutLimit`'s amount to be in terms of the provided currency.
|
|
426
|
+
if (payoutLimit.amount != 0 && payoutLimit.currency != targetCurrency) {
|
|
427
|
+
uint256 converted = mulDiv(
|
|
428
|
+
payoutLimit.amount,
|
|
429
|
+
10 ** _MAX_FIXED_POINT_FIDELITY, // Use `_MAX_FIXED_POINT_FIDELITY` to keep as much of the
|
|
430
|
+
// `payoutLimitRemaining`'s fidelity as possible when converting.
|
|
431
|
+
PRICES.pricePerUnitOf({
|
|
432
|
+
projectId: projectId,
|
|
433
|
+
pricingCurrency: payoutLimit.currency,
|
|
434
|
+
unitCurrency: targetCurrency,
|
|
435
|
+
decimals: _MAX_FIXED_POINT_FIDELITY
|
|
436
|
+
})
|
|
437
|
+
);
|
|
438
|
+
if (converted > type(uint224).max) revert JBTerminalStore_Uint224Overflow(converted);
|
|
439
|
+
payoutLimit.amount = uint224(converted);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Decrement from the balance until it reaches zero.
|
|
443
|
+
if (surplus > payoutLimit.amount) {
|
|
444
|
+
surplus -= payoutLimit.amount;
|
|
445
|
+
} else {
|
|
446
|
+
return 0;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
//*********************************************************************//
|
|
452
|
+
// ---------------------- external transactions ---------------------- //
|
|
453
|
+
//*********************************************************************//
|
|
454
|
+
|
|
455
|
+
/// @notice Records funds being added to a project's balance.
|
|
456
|
+
/// @param projectId The ID of the project which funds are being added to the balance of.
|
|
457
|
+
/// @param token The token being added to the balance.
|
|
458
|
+
/// @param amount The amount of terminal tokens added, as a fixed point number with the same amount of decimals as
|
|
459
|
+
/// its relative terminal.
|
|
460
|
+
function recordAddedBalanceFor(uint256 projectId, address token, uint256 amount) external override {
|
|
461
|
+
// Increment the balance.
|
|
462
|
+
balanceOf[msg.sender][projectId][token] = balanceOf[msg.sender][projectId][token] + amount;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/// @notice Records a cash out from a project.
|
|
466
|
+
/// @dev Cashs out the project's tokens according to values provided by the ruleset's data hook. If the ruleset has
|
|
467
|
+
/// no
|
|
468
|
+
/// data hook, cashs out tokens along a cash out bonding curve that is a function of the number of tokens being
|
|
469
|
+
/// burned.
|
|
470
|
+
/// @param holder The account that is cashing out tokens.
|
|
471
|
+
/// @param projectId The ID of the project being cashing out from.
|
|
472
|
+
/// @param cashOutCount The number of project tokens to cash out, as a fixed point number with 18 decimals.
|
|
473
|
+
/// @param accountingContext The accounting context of the token being reclaimed by the cash out.
|
|
474
|
+
/// @param balanceAccountingContexts The accounting contexts of the tokens whose balances should contribute to the
|
|
475
|
+
/// surplus being reclaimed from.
|
|
476
|
+
/// @param metadata Bytes to send to the data hook, if the project's current ruleset specifies one.
|
|
477
|
+
/// @return ruleset The ruleset during the cash out was made during, as a `JBRuleset` struct. This ruleset will
|
|
478
|
+
/// have a cash out tax rate provided by the cash out hook if applicable.
|
|
479
|
+
/// @return reclaimAmount The amount of tokens reclaimed from the terminal, as a fixed point number with 18
|
|
480
|
+
/// decimals.
|
|
481
|
+
/// @return cashOutTaxRate The cash out tax rate influencing the reclaim amount.
|
|
482
|
+
/// @return hookSpecifications A list of cash out hooks, including data and amounts to send to them. The terminal
|
|
483
|
+
/// should fulfill these specifications.
|
|
484
|
+
function recordCashOutFor(
|
|
485
|
+
address holder,
|
|
486
|
+
uint256 projectId,
|
|
487
|
+
uint256 cashOutCount,
|
|
488
|
+
JBAccountingContext calldata accountingContext,
|
|
489
|
+
JBAccountingContext[] calldata balanceAccountingContexts,
|
|
490
|
+
bytes memory metadata
|
|
491
|
+
)
|
|
492
|
+
external
|
|
493
|
+
override
|
|
494
|
+
returns (
|
|
495
|
+
JBRuleset memory ruleset,
|
|
496
|
+
uint256 reclaimAmount,
|
|
497
|
+
uint256 cashOutTaxRate,
|
|
498
|
+
JBCashOutHookSpecification[] memory hookSpecifications
|
|
499
|
+
)
|
|
500
|
+
{
|
|
501
|
+
// Get a reference to the project's current ruleset.
|
|
502
|
+
ruleset = RULESETS.currentOf(projectId);
|
|
503
|
+
|
|
504
|
+
// Get the current surplus amount.
|
|
505
|
+
// Use the local surplus if the ruleset specifies that it should be used. Otherwise, use the project's total
|
|
506
|
+
// surplus across all of its terminals.
|
|
507
|
+
uint256 currentSurplus = ruleset.useTotalSurplusForCashOuts()
|
|
508
|
+
? JBSurplus.currentSurplusOf({
|
|
509
|
+
projectId: projectId,
|
|
510
|
+
terminals: DIRECTORY.terminalsOf(projectId),
|
|
511
|
+
accountingContexts: new JBAccountingContext[](0),
|
|
512
|
+
decimals: accountingContext.decimals,
|
|
513
|
+
currency: accountingContext.currency
|
|
514
|
+
})
|
|
515
|
+
: _surplusFrom({
|
|
516
|
+
terminal: msg.sender,
|
|
517
|
+
projectId: projectId,
|
|
518
|
+
accountingContexts: balanceAccountingContexts,
|
|
519
|
+
ruleset: ruleset,
|
|
520
|
+
targetDecimals: accountingContext.decimals,
|
|
521
|
+
targetCurrency: accountingContext.currency
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
// Get the total number of outstanding project tokens.
|
|
525
|
+
uint256 totalSupply =
|
|
526
|
+
IJBController(address(DIRECTORY.controllerOf(projectId))).totalTokenSupplyWithReservedTokensOf(projectId);
|
|
527
|
+
|
|
528
|
+
// Can't cash out more tokens than are in the supply.
|
|
529
|
+
if (cashOutCount > totalSupply) revert JBTerminalStore_InsufficientTokens(cashOutCount, totalSupply);
|
|
530
|
+
|
|
531
|
+
// SECURITY NOTE: The data hook has absolute control over cash-out economics.
|
|
532
|
+
// It can set totalSupply, cashOutCount, and cashOutTaxRate to arbitrary values,
|
|
533
|
+
// completely overriding the terminal's bonding curve math. For example, setting
|
|
534
|
+
// totalSupply = surplus makes reclaimAmount = cashOutCount, bypassing the curve.
|
|
535
|
+
// Project owners MUST audit their data hooks with the same rigor as the terminal.
|
|
536
|
+
|
|
537
|
+
// If the ruleset has a data hook which is enabled for cash outs, use it to derive a claim amount and memo.
|
|
538
|
+
if (ruleset.useDataHookForCashOut() && ruleset.dataHook() != address(0)) {
|
|
539
|
+
// Create the cash out context that'll be sent to the data hook.
|
|
540
|
+
JBBeforeCashOutRecordedContext memory context = JBBeforeCashOutRecordedContext({
|
|
541
|
+
terminal: msg.sender,
|
|
542
|
+
holder: holder,
|
|
543
|
+
projectId: projectId,
|
|
544
|
+
rulesetId: ruleset.id,
|
|
545
|
+
cashOutCount: cashOutCount,
|
|
546
|
+
totalSupply: totalSupply,
|
|
547
|
+
surplus: JBTokenAmount({
|
|
548
|
+
token: accountingContext.token,
|
|
549
|
+
value: currentSurplus,
|
|
550
|
+
decimals: accountingContext.decimals,
|
|
551
|
+
currency: accountingContext.currency
|
|
552
|
+
}),
|
|
553
|
+
useTotalSurplus: ruleset.useTotalSurplusForCashOuts(),
|
|
554
|
+
cashOutTaxRate: ruleset.cashOutTaxRate(),
|
|
555
|
+
metadata: metadata
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
(cashOutTaxRate, cashOutCount, totalSupply, hookSpecifications) =
|
|
559
|
+
IJBRulesetDataHook(ruleset.dataHook()).beforeCashOutRecordedWith(context);
|
|
560
|
+
} else {
|
|
561
|
+
cashOutTaxRate = ruleset.cashOutTaxRate();
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
if (currentSurplus != 0) {
|
|
565
|
+
// Calculate reclaim amount using the current surplus amount.
|
|
566
|
+
reclaimAmount = JBCashOuts.cashOutFrom({
|
|
567
|
+
surplus: currentSurplus,
|
|
568
|
+
cashOutCount: cashOutCount,
|
|
569
|
+
totalSupply: totalSupply,
|
|
570
|
+
cashOutTaxRate: cashOutTaxRate
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// Keep a reference to the amount that should be added to the project's balance.
|
|
575
|
+
uint256 balanceDiff = reclaimAmount;
|
|
576
|
+
|
|
577
|
+
// Ensure that the specifications have valid amounts.
|
|
578
|
+
if (hookSpecifications.length != 0) {
|
|
579
|
+
// Keep a reference to the number of cash out hooks specified.
|
|
580
|
+
uint256 numberOfSpecifications = hookSpecifications.length;
|
|
581
|
+
|
|
582
|
+
// Loop through each specification.
|
|
583
|
+
for (uint256 i; i < numberOfSpecifications; i++) {
|
|
584
|
+
// Get a reference to the specification's amount.
|
|
585
|
+
uint256 specificationAmount = hookSpecifications[i].amount;
|
|
586
|
+
|
|
587
|
+
// Ensure the amount is non-zero.
|
|
588
|
+
if (specificationAmount != 0) {
|
|
589
|
+
// Increment the total amount being subtracted from the balance.
|
|
590
|
+
balanceDiff += specificationAmount;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// The amount being reclaimed must be within the project's balance.
|
|
596
|
+
if (balanceDiff > balanceOf[msg.sender][projectId][accountingContext.token]) {
|
|
597
|
+
revert JBTerminalStore_InadequateTerminalStoreBalance(
|
|
598
|
+
balanceDiff, balanceOf[msg.sender][projectId][accountingContext.token]
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// Remove the reclaimed funds from the project's balance.
|
|
603
|
+
if (balanceDiff != 0) {
|
|
604
|
+
unchecked {
|
|
605
|
+
balanceOf[msg.sender][projectId][accountingContext.token] =
|
|
606
|
+
balanceOf[msg.sender][projectId][accountingContext.token] - balanceDiff;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/// @notice Records a payment to a project.
|
|
612
|
+
/// @dev Mints the project's tokens according to values provided by the ruleset's data hook. If the ruleset has no
|
|
613
|
+
/// data hook, mints tokens in proportion with the amount paid.
|
|
614
|
+
/// @param payer The address that made the payment to the terminal.
|
|
615
|
+
/// @param amount The amount of tokens being paid. Includes the token being paid, their value, the number of
|
|
616
|
+
/// decimals included, and the currency of the amount.
|
|
617
|
+
/// @param projectId The ID of the project being paid.
|
|
618
|
+
/// @param beneficiary The address that should be the beneficiary of anything the payment yields (including project
|
|
619
|
+
/// tokens minted by the payment).
|
|
620
|
+
/// @param metadata Bytes to send to the data hook, if the project's current ruleset specifies one.
|
|
621
|
+
/// @return ruleset The ruleset the payment was made during, as a `JBRuleset` struct.
|
|
622
|
+
/// @return tokenCount The number of project tokens that were minted, as a fixed point number with 18 decimals.
|
|
623
|
+
/// @return hookSpecifications A list of pay hooks, including data and amounts to send to them. The terminal should
|
|
624
|
+
/// fulfill these specifications.
|
|
625
|
+
function recordPaymentFrom(
|
|
626
|
+
address payer,
|
|
627
|
+
JBTokenAmount calldata amount,
|
|
628
|
+
uint256 projectId,
|
|
629
|
+
address beneficiary,
|
|
630
|
+
bytes calldata metadata
|
|
631
|
+
)
|
|
632
|
+
external
|
|
633
|
+
override
|
|
634
|
+
returns (JBRuleset memory ruleset, uint256 tokenCount, JBPayHookSpecification[] memory hookSpecifications)
|
|
635
|
+
{
|
|
636
|
+
// Get a reference to the project's current ruleset.
|
|
637
|
+
ruleset = RULESETS.currentOf(projectId);
|
|
638
|
+
|
|
639
|
+
// The project must have a ruleset.
|
|
640
|
+
if (ruleset.cycleNumber == 0) revert JBTerminalStore_RulesetNotFound(projectId);
|
|
641
|
+
|
|
642
|
+
// The ruleset must not have payments paused.
|
|
643
|
+
if (ruleset.pausePay()) revert JBTerminalStore_RulesetPaymentPaused();
|
|
644
|
+
|
|
645
|
+
// The weight according to which new tokens are to be minted, as a fixed point number with 18 decimals.
|
|
646
|
+
uint256 weight;
|
|
647
|
+
|
|
648
|
+
// SECURITY NOTE: The data hook has absolute control over payment token minting.
|
|
649
|
+
// It can return an arbitrary weight (overriding the ruleset's weight) and hook specifications
|
|
650
|
+
// that divert payment funds to external hooks before they reach the project's balance.
|
|
651
|
+
// Project owners MUST audit their data hooks with the same rigor as the terminal.
|
|
652
|
+
|
|
653
|
+
// If the ruleset has a data hook enabled for payments, use it to derive a weight and memo.
|
|
654
|
+
if (ruleset.useDataHookForPay() && ruleset.dataHook() != address(0)) {
|
|
655
|
+
// Create the pay context that'll be sent to the data hook.
|
|
656
|
+
JBBeforePayRecordedContext memory context = JBBeforePayRecordedContext({
|
|
657
|
+
terminal: msg.sender,
|
|
658
|
+
payer: payer,
|
|
659
|
+
amount: amount,
|
|
660
|
+
projectId: projectId,
|
|
661
|
+
rulesetId: ruleset.id,
|
|
662
|
+
beneficiary: beneficiary,
|
|
663
|
+
weight: ruleset.weight,
|
|
664
|
+
reservedPercent: ruleset.reservedPercent(),
|
|
665
|
+
metadata: metadata
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
(weight, hookSpecifications) = IJBRulesetDataHook(ruleset.dataHook()).beforePayRecordedWith(context);
|
|
669
|
+
}
|
|
670
|
+
// Otherwise use the ruleset's weight
|
|
671
|
+
else {
|
|
672
|
+
weight = ruleset.weight;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// Keep a reference to the amount that should be added to the project's balance.
|
|
676
|
+
uint256 balanceDiff = amount.value;
|
|
677
|
+
|
|
678
|
+
// Scoped section preventing stack too deep.
|
|
679
|
+
{
|
|
680
|
+
// Keep a reference to the number of hook specifications.
|
|
681
|
+
uint256 numberOfSpecifications = hookSpecifications.length;
|
|
682
|
+
|
|
683
|
+
// Ensure that the specifications have valid amounts.
|
|
684
|
+
for (uint256 i; i < numberOfSpecifications; i++) {
|
|
685
|
+
// Get a reference to the specification's amount.
|
|
686
|
+
uint256 specifiedAmount = hookSpecifications[i].amount;
|
|
687
|
+
|
|
688
|
+
// Ensure the amount is non-zero.
|
|
689
|
+
if (specifiedAmount != 0) {
|
|
690
|
+
// Can't send more to hook than was paid.
|
|
691
|
+
if (specifiedAmount > balanceDiff) {
|
|
692
|
+
revert JBTerminalStore_InvalidAmountToForwardHook(specifiedAmount, balanceDiff);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// Decrement the total amount being added to the local balance.
|
|
696
|
+
balanceDiff -= specifiedAmount;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// If there's no amount being recorded, there's nothing left to do.
|
|
702
|
+
if (amount.value == 0) return (ruleset, 0, hookSpecifications);
|
|
703
|
+
|
|
704
|
+
// Add the correct balance difference to the token balance of the project.
|
|
705
|
+
if (balanceDiff != 0) {
|
|
706
|
+
balanceOf[msg.sender][projectId][amount.token] =
|
|
707
|
+
balanceOf[msg.sender][projectId][amount.token] + balanceDiff;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// If there's no weight, the token count must be 0, so there's nothing left to do.
|
|
711
|
+
if (weight == 0) return (ruleset, 0, hookSpecifications);
|
|
712
|
+
|
|
713
|
+
// If the terminal should base its weight on a currency other than the terminal's currency, determine the
|
|
714
|
+
// factor. The weight is always a fixed point mumber with 18 decimals. To ensure this, the ratio should use the
|
|
715
|
+
// same
|
|
716
|
+
// number of decimals as the `amount`.
|
|
717
|
+
uint256 weightRatio = amount.currency == ruleset.baseCurrency()
|
|
718
|
+
? 10 ** amount.decimals
|
|
719
|
+
: PRICES.pricePerUnitOf({
|
|
720
|
+
projectId: projectId,
|
|
721
|
+
pricingCurrency: amount.currency,
|
|
722
|
+
unitCurrency: ruleset.baseCurrency(),
|
|
723
|
+
decimals: amount.decimals
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
// Find the number of tokens to mint, as a fixed point number with as many decimals as `weight` has.
|
|
727
|
+
tokenCount = mulDiv(amount.value, weight, weightRatio);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/// @notice Records a payout from a project.
|
|
731
|
+
/// @dev The balance is decremented and the used payout limit is incremented before the payout limit validation.
|
|
732
|
+
/// This is safe because the entire transaction reverts atomically if the validation fails, but callers should
|
|
733
|
+
/// be aware of this ordering.
|
|
734
|
+
/// @param projectId The ID of the project that is paying out funds.
|
|
735
|
+
/// @param accountingContext The context of the token being paid out.
|
|
736
|
+
/// @param amount The amount to pay out (use from the payout limit), as a fixed point number.
|
|
737
|
+
/// @param currency The currency of the `amount`. This must match the project's current ruleset's currency.
|
|
738
|
+
/// @return ruleset The ruleset the payout was made during, as a `JBRuleset` struct.
|
|
739
|
+
/// @return amountPaidOut The amount of terminal tokens paid out, as a fixed point number with the same amount of
|
|
740
|
+
/// decimals as its relative terminal.
|
|
741
|
+
function recordPayoutFor(
|
|
742
|
+
uint256 projectId,
|
|
743
|
+
JBAccountingContext calldata accountingContext,
|
|
744
|
+
uint256 amount,
|
|
745
|
+
uint256 currency
|
|
746
|
+
)
|
|
747
|
+
external
|
|
748
|
+
override
|
|
749
|
+
returns (JBRuleset memory ruleset, uint256 amountPaidOut)
|
|
750
|
+
{
|
|
751
|
+
// Get a reference to the project's current ruleset.
|
|
752
|
+
ruleset = RULESETS.currentOf(projectId);
|
|
753
|
+
|
|
754
|
+
// Convert the amount to the balance's currency.
|
|
755
|
+
amountPaidOut = (currency == accountingContext.currency)
|
|
756
|
+
? amount
|
|
757
|
+
: mulDiv(
|
|
758
|
+
amount,
|
|
759
|
+
10 ** _MAX_FIXED_POINT_FIDELITY, // Use `_MAX_FIXED_POINT_FIDELITY` to keep as much of the `_amount`'s
|
|
760
|
+
// fidelity as possible when converting.
|
|
761
|
+
PRICES.pricePerUnitOf({
|
|
762
|
+
projectId: projectId,
|
|
763
|
+
pricingCurrency: currency,
|
|
764
|
+
unitCurrency: accountingContext.currency,
|
|
765
|
+
decimals: _MAX_FIXED_POINT_FIDELITY
|
|
766
|
+
})
|
|
767
|
+
);
|
|
768
|
+
|
|
769
|
+
// The amount being paid out must be available.
|
|
770
|
+
if (amountPaidOut > balanceOf[msg.sender][projectId][accountingContext.token]) {
|
|
771
|
+
revert JBTerminalStore_InadequateTerminalStoreBalance(
|
|
772
|
+
amountPaidOut, balanceOf[msg.sender][projectId][accountingContext.token]
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// Removed the paid out funds from the project's token balance.
|
|
777
|
+
unchecked {
|
|
778
|
+
balanceOf[msg.sender][projectId][accountingContext.token] =
|
|
779
|
+
balanceOf[msg.sender][projectId][accountingContext.token] - amountPaidOut;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
// The new total amount which has been paid out during this ruleset.
|
|
783
|
+
uint256 newUsedPayoutLimitOf =
|
|
784
|
+
usedPayoutLimitOf[msg.sender][projectId][accountingContext.token][ruleset.cycleNumber][currency] + amount;
|
|
785
|
+
|
|
786
|
+
// Store the new amount.
|
|
787
|
+
usedPayoutLimitOf[msg.sender][projectId][accountingContext.token][ruleset.cycleNumber][currency] =
|
|
788
|
+
newUsedPayoutLimitOf;
|
|
789
|
+
|
|
790
|
+
// Amount must be within what is still available to pay out.
|
|
791
|
+
uint256 payoutLimit = IJBController(address(DIRECTORY.controllerOf(projectId))).FUND_ACCESS_LIMITS()
|
|
792
|
+
.payoutLimitOf({
|
|
793
|
+
projectId: projectId,
|
|
794
|
+
rulesetId: ruleset.id,
|
|
795
|
+
terminal: msg.sender,
|
|
796
|
+
token: accountingContext.token,
|
|
797
|
+
currency: currency
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
// Make sure the new used amount is within the payout limit.
|
|
801
|
+
if (newUsedPayoutLimitOf > payoutLimit || payoutLimit == 0) {
|
|
802
|
+
revert JBTerminalStore_InadequateControllerPayoutLimit(newUsedPayoutLimitOf, payoutLimit);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
/// @notice Records the migration of funds from this store.
|
|
807
|
+
/// @param projectId The ID of the project being migrated.
|
|
808
|
+
/// @param token The token being migrated.
|
|
809
|
+
/// @return balance The project's current balance (which is being migrated), as a fixed point number with the same
|
|
810
|
+
/// amount of decimals as its relative terminal.
|
|
811
|
+
function recordTerminalMigration(uint256 projectId, address token) external override returns (uint256 balance) {
|
|
812
|
+
// Get a reference to the project's current ruleset.
|
|
813
|
+
JBRuleset memory ruleset = RULESETS.currentOf(projectId);
|
|
814
|
+
|
|
815
|
+
// Terminal migration must be allowed.
|
|
816
|
+
if (!ruleset.allowTerminalMigration()) {
|
|
817
|
+
revert JBTerminalStore_TerminalMigrationNotAllowed();
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
// Return the current balance, which is the amount being migrated.
|
|
821
|
+
balance = balanceOf[msg.sender][projectId][token];
|
|
822
|
+
|
|
823
|
+
// Set the balance to 0.
|
|
824
|
+
balanceOf[msg.sender][projectId][token] = 0;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
/// @notice Records a use of a project's surplus allowance.
|
|
828
|
+
/// @dev When surplus allowance is "used", it is taken out of the project's surplus within a terminal.
|
|
829
|
+
/// @param projectId The ID of the project to use the surplus allowance of.
|
|
830
|
+
/// @param accountingContext The accounting context of the token whose balances should contribute to the surplus
|
|
831
|
+
/// allowance being reclaimed from.
|
|
832
|
+
/// @param amount The amount to use from the surplus allowance, as a fixed point number.
|
|
833
|
+
/// @param currency The currency of the `amount`. Must match the currency of the surplus allowance.
|
|
834
|
+
/// @return ruleset The ruleset during the surplus allowance is being used during, as a `JBRuleset` struct.
|
|
835
|
+
/// @return usedAmount The amount of terminal tokens used, as a fixed point number with the same amount of decimals
|
|
836
|
+
/// as its relative terminal.
|
|
837
|
+
function recordUsedAllowanceOf(
|
|
838
|
+
uint256 projectId,
|
|
839
|
+
JBAccountingContext calldata accountingContext,
|
|
840
|
+
uint256 amount,
|
|
841
|
+
uint256 currency
|
|
842
|
+
)
|
|
843
|
+
external
|
|
844
|
+
override
|
|
845
|
+
returns (JBRuleset memory ruleset, uint256 usedAmount)
|
|
846
|
+
{
|
|
847
|
+
// Get a reference to the project's current ruleset.
|
|
848
|
+
ruleset = RULESETS.currentOf(projectId);
|
|
849
|
+
|
|
850
|
+
// Convert the amount to this store's terminal's token.
|
|
851
|
+
usedAmount = currency == accountingContext.currency
|
|
852
|
+
? amount
|
|
853
|
+
: mulDiv(
|
|
854
|
+
amount,
|
|
855
|
+
10 ** _MAX_FIXED_POINT_FIDELITY, // Use `_MAX_FIXED_POINT_FIDELITY` to keep as much of the `amount`'s
|
|
856
|
+
// fidelity as possible when converting.
|
|
857
|
+
PRICES.pricePerUnitOf({
|
|
858
|
+
projectId: projectId,
|
|
859
|
+
pricingCurrency: currency,
|
|
860
|
+
unitCurrency: accountingContext.currency,
|
|
861
|
+
decimals: _MAX_FIXED_POINT_FIDELITY
|
|
862
|
+
})
|
|
863
|
+
);
|
|
864
|
+
|
|
865
|
+
// Set the token being used as the only one to look for surplus within.
|
|
866
|
+
JBAccountingContext[] memory accountingContexts = new JBAccountingContext[](1);
|
|
867
|
+
accountingContexts[0] = accountingContext;
|
|
868
|
+
|
|
869
|
+
uint256 surplus = _surplusFrom({
|
|
870
|
+
terminal: msg.sender,
|
|
871
|
+
projectId: projectId,
|
|
872
|
+
accountingContexts: accountingContexts,
|
|
873
|
+
ruleset: ruleset,
|
|
874
|
+
targetDecimals: accountingContext.decimals,
|
|
875
|
+
targetCurrency: accountingContext.currency
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
// The amount being used must be available in the surplus.
|
|
879
|
+
if (usedAmount > surplus) revert JBTerminalStore_InadequateTerminalStoreBalance(usedAmount, surplus);
|
|
880
|
+
|
|
881
|
+
// Update the project's balance.
|
|
882
|
+
balanceOf[msg.sender][projectId][accountingContext.token] =
|
|
883
|
+
balanceOf[msg.sender][projectId][accountingContext.token] - usedAmount;
|
|
884
|
+
|
|
885
|
+
// Get a reference to the new used surplus allowance for this ruleset ID.
|
|
886
|
+
uint256 newUsedSurplusAllowanceOf =
|
|
887
|
+
usedSurplusAllowanceOf[msg.sender][projectId][accountingContext.token][ruleset.id][currency] + amount;
|
|
888
|
+
|
|
889
|
+
// Store the incremented value.
|
|
890
|
+
usedSurplusAllowanceOf[msg.sender][projectId][accountingContext.token][ruleset.id][currency] =
|
|
891
|
+
newUsedSurplusAllowanceOf;
|
|
892
|
+
|
|
893
|
+
// There must be sufficient surplus allowance available.
|
|
894
|
+
uint256 surplusAllowance = IJBController(address(DIRECTORY.controllerOf(projectId))).FUND_ACCESS_LIMITS()
|
|
895
|
+
.surplusAllowanceOf({
|
|
896
|
+
projectId: projectId,
|
|
897
|
+
rulesetId: ruleset.id,
|
|
898
|
+
terminal: msg.sender,
|
|
899
|
+
token: accountingContext.token,
|
|
900
|
+
currency: currency
|
|
901
|
+
});
|
|
902
|
+
|
|
903
|
+
// Make sure the new used amount is within the allowance.
|
|
904
|
+
if (newUsedSurplusAllowanceOf > surplusAllowance || surplusAllowance == 0) {
|
|
905
|
+
revert JBTerminalStore_InadequateControllerAllowance(newUsedSurplusAllowanceOf, surplusAllowance);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|