@bananapus/core-v6 0.0.4 → 0.0.6
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/README.md +93 -33
- package/SKILLS.md +166 -30
- package/foundry.toml +1 -1
- package/package.json +1 -1
- package/script/Deploy.s.sol +1 -1
- package/script/DeployPeriphery.s.sol +1 -1
- package/script/helpers/CoreDeploymentLib.sol +1 -1
- package/src/JBChainlinkV3PriceFeed.sol +1 -1
- package/src/JBChainlinkV3SequencerPriceFeed.sol +1 -1
- package/src/JBController.sol +1 -1
- package/src/JBDeadline.sol +1 -1
- package/src/JBDirectory.sol +1 -1
- package/src/JBERC20.sol +1 -1
- package/src/JBFeelessAddresses.sol +1 -1
- package/src/JBFundAccessLimits.sol +1 -1
- package/src/JBMultiTerminal.sol +1 -1
- package/src/JBPermissions.sol +1 -1
- package/src/JBPrices.sol +1 -1
- package/src/JBProjects.sol +1 -1
- package/src/JBRulesets.sol +1 -1
- package/src/JBSplits.sol +1 -1
- package/src/JBTerminalStore.sol +1 -1
- package/src/JBTokens.sol +1 -1
- package/src/libraries/JBMetadataResolver.sol +7 -7
- package/src/periphery/JBDeadline1Day.sol +1 -1
- package/src/periphery/JBDeadline3Days.sol +1 -1
- package/src/periphery/JBDeadline3Hours.sol +1 -1
- package/src/periphery/JBDeadline7Days.sol +1 -1
- package/src/periphery/JBMatchingPriceFeed.sol +1 -1
- package/test/FlashLoanAttacks.t.sol +8 -13
- package/test/PermissionsInvariant.t.sol +403 -0
- package/test/TestJBERC20Inheritance.sol +1 -1
- package/test/TestMetadataParserLib.sol +1 -1
- package/test/helpers/JBTest.sol +1 -1
- package/test/helpers/MetadataResolverHelper.sol +1 -1
- package/test/mock/MockERC20.sol +1 -1
- package/test/mock/MockMaliciousBeneficiary.sol +1 -1
- package/test/mock/MockMaliciousSplitHook.sol +1 -1
- package/test/mock/MockPriceFeed.sol +1 -1
- package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +1 -1
- package/test/units/static/JBController/JBControllerSetup.sol +1 -1
- package/test/units/static/JBController/TestBurnTokensOf.sol +1 -1
- package/test/units/static/JBController/TestClaimTokensFor.sol +1 -1
- package/test/units/static/JBController/TestDeployErc20For.sol +1 -1
- package/test/units/static/JBController/TestLaunchProjectFor.sol +1 -1
- package/test/units/static/JBController/TestLaunchRulesetsFor.sol +1 -1
- package/test/units/static/JBController/TestMigrateController.sol +1 -1
- package/test/units/static/JBController/TestMintTokensOfUnits.sol +1 -1
- package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +1 -1
- package/test/units/static/JBController/TestReceiveMigrationFrom.sol +1 -1
- package/test/units/static/JBController/TestRulesetViews.sol +1 -1
- package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +1 -1
- package/test/units/static/JBController/TestSetSplitGroupsOf.sol +1 -1
- package/test/units/static/JBController/TestSetTokenFor.sol +1 -1
- package/test/units/static/JBController/TestSetUriOf.sol +1 -1
- package/test/units/static/JBController/TestTransferCreditsFrom.sol +1 -1
- package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +1 -1
- package/test/units/static/JBDirectory/JBDirectorySetup.sol +1 -1
- package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +1 -1
- package/test/units/static/JBDirectory/TestSetControllerOf.sol +1 -1
- package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +1 -1
- package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +1 -1
- package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +1 -1
- package/test/units/static/JBERC20/JBERC20Setup.sol +1 -1
- package/test/units/static/JBERC20/SigUtils.sol +1 -1
- package/test/units/static/JBERC20/TestInitialize.sol +1 -1
- package/test/units/static/JBERC20/TestName.sol +1 -1
- package/test/units/static/JBERC20/TestNonces.sol +1 -1
- package/test/units/static/JBERC20/TestSymbol.sol +1 -1
- package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +1 -1
- package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +1 -1
- package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +1 -1
- package/test/units/static/JBFees/TestFeesFuzz.sol +1 -1
- package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +1 -1
- package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +1 -1
- package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +1 -1
- package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +1 -1
- package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +1 -1
- package/test/units/static/JBMetadataResolver/TestMetadataResolverM20M21.sol +1 -1
- package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestPay.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +1 -1
- package/test/units/static/JBPermissions/JBPermissionsSetup.sol +1 -1
- package/test/units/static/JBPermissions/TestHasPermission.sol +1 -1
- package/test/units/static/JBPermissions/TestHasPermissions.sol +1 -1
- package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +1 -1
- package/test/units/static/JBPrices/JBPricesSetup.sol +1 -1
- package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +1 -1
- package/test/units/static/JBPrices/TestPricePerUnitOf.sol +1 -1
- package/test/units/static/JBPrices/TestPrices.sol +1 -1
- package/test/units/static/JBProjects/JBProjectsSetup.sol +1 -1
- package/test/units/static/JBProjects/TestCreateFor.sol +1 -1
- package/test/units/static/JBProjects/TestInitialProject.sol +1 -1
- package/test/units/static/JBProjects/TestInterfaces.sol +1 -1
- package/test/units/static/JBProjects/TestSetResolver.sol +1 -1
- package/test/units/static/JBProjects/TestTokenUri.sol +1 -1
- package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +1 -1
- package/test/units/static/JBRulesets/JBRulesetsSetup.sol +1 -1
- package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +1 -1
- package/test/units/static/JBRulesets/TestCurrentOf.sol +1 -1
- package/test/units/static/JBRulesets/TestGetRulesetOf.sol +1 -1
- package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +1 -1
- package/test/units/static/JBRulesets/TestRulesets.sol +1 -1
- package/test/units/static/JBRulesets/TestRulesetsOf.sol +1 -1
- package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +1 -1
- package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +1 -1
- package/test/units/static/JBSplits/JBSplitsSetup.sol +1 -1
- package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +1 -1
- package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +1 -1
- package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +1 -1
- package/test/units/static/JBSplits/TestSplitsOf.sol +1 -1
- package/test/units/static/JBSplits/TestSplitsPacking.sol +1 -1
- package/test/units/static/JBSurplus/TestSurplusFuzz.sol +1 -1
- package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +1 -1
- package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +1 -1
- package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +1 -1
- package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +1 -1
- package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +1 -1
- package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +1 -1
- package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +1 -1
- package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +1 -1
- package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +1 -1
- package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +1 -1
- package/test/units/static/JBTokens/JBTokensSetup.sol +1 -1
- package/test/units/static/JBTokens/TestBurnFrom.sol +1 -1
- package/test/units/static/JBTokens/TestClaimTokensFor.sol +1 -1
- package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +1 -1
- package/test/units/static/JBTokens/TestMintFor.sol +1 -1
- package/test/units/static/JBTokens/TestSetTokenFor.sol +1 -1
- package/test/units/static/JBTokens/TestTotalBalanceOf.sol +1 -1
- package/test/units/static/JBTokens/TestTotalSupplyOf.sol +1 -1
- package/test/units/static/JBTokens/TestTransferCreditsFrom.sol +1 -1
package/README.md
CHANGED
|
@@ -8,77 +8,127 @@ For full documentation, see [docs.juicebox.money](https://docs.juicebox.money/).
|
|
|
8
8
|
|
|
9
9
|
Juicebox projects have two main entry points:
|
|
10
10
|
|
|
11
|
-
- **Terminals** handle inflows and outflows of funds
|
|
11
|
+
- **Terminals** handle inflows and outflows of funds -- payments, cash outs, payouts, and surplus allowance usage. Each project can use multiple terminals, and a single terminal can serve many projects. `JBMultiTerminal` is the standard implementation.
|
|
12
12
|
- **Controllers** manage rulesets and tokens. `JBController` is the standard implementation that coordinates ruleset queuing, token minting/burning, splits, and fund access limits.
|
|
13
13
|
|
|
14
14
|
`JBDirectory` maps each project to its controller and terminals.
|
|
15
15
|
|
|
16
16
|
### Rulesets
|
|
17
17
|
|
|
18
|
-
A project's behavior is governed by a queue of **rulesets**. Each ruleset defines the rules that apply for a specific duration: payment weight (tokens minted per unit paid), cash out rate, reserved
|
|
18
|
+
A project's behavior is governed by a queue of **rulesets**. Each ruleset defines the rules that apply for a specific duration: payment weight (tokens minted per unit paid), cash out tax rate, reserved percent, payout limits, approval hooks, and more. When a ruleset ends, the next one in the queue takes effect. If the queue is empty, the current ruleset keeps cycling with weight decay applied each cycle. Rulesets give project creators the ability to evolve their project's rules while offering supporters contractual guarantees about the future.
|
|
19
|
+
|
|
20
|
+
Key ruleset behaviors:
|
|
21
|
+
- **Weight** determines token issuance per unit paid. A weight of 1 means "inherit decayed weight from the previous ruleset". A weight of 0 means "no issuance".
|
|
22
|
+
- **Weight decay** is controlled by `weightCutPercent`. Each cycle, the weight is reduced by this percent (9-decimal precision out of `1_000_000_000`).
|
|
23
|
+
- **Duration of 0** means the ruleset never expires and must be explicitly replaced by a new queued ruleset (which takes effect immediately).
|
|
24
|
+
- **Approval hooks** can gate whether queued rulesets take effect. For example, `JBDeadline` requires rulesets to be queued a minimum number of seconds before the current ruleset ends.
|
|
19
25
|
|
|
20
26
|
### Fund Distribution
|
|
21
27
|
|
|
22
|
-
Funds can be accessed through **payouts** (distributed to splits within payout limits, resetting each ruleset) or **surplus allowance** (discretionary withdrawal of surplus funds, does not reset). Funds beyond payout limits are surplus
|
|
28
|
+
Funds can be accessed through **payouts** (distributed to splits within payout limits, resetting each ruleset cycle) or **surplus allowance** (discretionary withdrawal of surplus funds, does not reset each cycle). Funds beyond payout limits are surplus -- available for cash outs if the project's cash out tax rate allows it.
|
|
29
|
+
|
|
30
|
+
- **Payout limits** are denominated in configurable currencies and can be set per terminal/token. Multiple limits in different currencies can be active simultaneously.
|
|
31
|
+
- **Surplus allowances** allow project owners to withdraw surplus funds up to a configured amount, also denominated in configurable currencies.
|
|
23
32
|
|
|
24
33
|
### Payments, Tokens, and Cash Outs
|
|
25
34
|
|
|
26
|
-
Payments mint credits (or ERC-20 tokens if
|
|
35
|
+
Payments mint credits (or ERC-20 tokens if an ERC-20 has been deployed for the project) for the payer based on the current ruleset's weight. The number of tokens minted can be influenced by a data hook.
|
|
36
|
+
|
|
37
|
+
Credits and tokens can be **cashed out** to reclaim surplus funds along a bonding curve determined by the cash out tax rate:
|
|
38
|
+
- A **0% tax rate** gives proportional (1:1) redemption of surplus.
|
|
39
|
+
- A **100% tax rate** means nothing can be reclaimed (all surplus is locked).
|
|
40
|
+
- Tax rates between 0% and 100% create a bonding curve that incentivizes holding -- later cashers-out get a better rate per token.
|
|
41
|
+
|
|
42
|
+
### Reserved Tokens
|
|
43
|
+
|
|
44
|
+
Each ruleset can define a `reservedPercent` (0-10,000 basis points). When tokens are minted from payments, this percentage is set aside. Reserved tokens accumulate in `pendingReservedTokenBalanceOf` and are distributed to the reserved token split group when `sendReservedTokensToSplitsOf` is called.
|
|
27
45
|
|
|
28
46
|
### Permissions
|
|
29
47
|
|
|
30
|
-
`JBPermissions` lets addresses delegate specific capabilities to operators, scoped by project ID. Each permission ID grants access to specific functions
|
|
48
|
+
`JBPermissions` lets addresses delegate specific capabilities to operators, scoped by project ID. Each permission ID grants access to specific functions. See [`JBPermissionIds`](https://github.com/Bananapus/nana-permission-ids-v6/blob/main/src/JBPermissionIds.sol) for the full list.
|
|
49
|
+
|
|
50
|
+
- Permission ID `255` is `ROOT` and grants all permissions for the scoped project.
|
|
51
|
+
- Project ID `0` is a wildcard, granting permissions across all projects (cannot be combined with `ROOT` for safety).
|
|
52
|
+
- ROOT operators can set non-ROOT permissions for other operators, but cannot grant ROOT or set wildcard-project permissions.
|
|
31
53
|
|
|
32
54
|
### Hooks
|
|
33
55
|
|
|
34
56
|
Hooks are customizable contracts that plug into protocol flows:
|
|
35
57
|
|
|
36
|
-
- **Approval hooks**
|
|
37
|
-
- **Data hooks**
|
|
38
|
-
- **Pay hooks**
|
|
39
|
-
- **Cash out hooks**
|
|
40
|
-
- **Split hooks**
|
|
58
|
+
- **Approval hooks** -- Gate whether the next queued ruleset can take effect (e.g., `JBDeadline` enforces a minimum queue time).
|
|
59
|
+
- **Data hooks** -- Override payment/cash-out weight, cash out tax rate, token counts, and specify pay/cash-out hooks to call. Data hooks can also grant `hasMintPermissionFor` to allow addresses to mint tokens on demand.
|
|
60
|
+
- **Pay hooks** -- Custom logic triggered after a payment is recorded (e.g., `JB721TiersHook` mints NFTs). Receive tokens and `JBAfterPayRecordedContext`.
|
|
61
|
+
- **Cash out hooks** -- Custom logic triggered after a cash out is recorded. Receive tokens and `JBAfterCashOutRecordedContext`.
|
|
62
|
+
- **Split hooks** -- Custom logic triggered when a payout or reserved token distribution is routed to a split. Receive tokens and `JBSplitHookContext`.
|
|
41
63
|
|
|
42
64
|
### Fees
|
|
43
65
|
|
|
44
|
-
`JBMultiTerminal` charges a 2.5% fee
|
|
66
|
+
`JBMultiTerminal` charges a 2.5% fee (`FEE = 25` out of `MAX_FEE = 1000`) on:
|
|
67
|
+
- Payouts to external addresses (not to other Juicebox projects).
|
|
68
|
+
- Surplus allowance usage.
|
|
69
|
+
- Cash outs when the cash out tax rate is below 100%.
|
|
70
|
+
|
|
71
|
+
Fees are paid to **project #1** (the fee beneficiary project, minted in the `JBProjects` constructor). Addresses on the `JBFeelessAddresses` allowlist are exempt from fees.
|
|
72
|
+
|
|
73
|
+
When a ruleset has `holdFees` enabled, fees are held for 28 days before being processed. During this period, if funds are returned to the project via `addToBalanceOf`, held fees can be unlocked and returned.
|
|
74
|
+
|
|
75
|
+
### Meta-Transactions
|
|
76
|
+
|
|
77
|
+
`JBController`, `JBMultiTerminal`, `JBProjects`, `JBPrices`, and `JBPermissions` support ERC-2771 meta-transactions through a trusted forwarder. This allows gasless interactions where a relayer submits transactions on behalf of users.
|
|
78
|
+
|
|
79
|
+
### Permit2
|
|
80
|
+
|
|
81
|
+
`JBMultiTerminal` integrates with Uniswap's [Permit2](https://github.com/Uniswap/permit2) for gas-efficient ERC-20 token approvals. Payers can include a `JBSingleAllowance` in the payment metadata to authorize token transfers without a separate approval transaction.
|
|
82
|
+
|
|
83
|
+
### Controller Migration
|
|
84
|
+
|
|
85
|
+
Projects can migrate between controllers using the `IJBMigratable` interface. The migration lifecycle calls `beforeReceiveMigrationFrom` on the new controller, then `migrate` on the old controller (while the directory still points to it), then updates the directory, and finally calls `afterReceiveMigrationFrom`. Terminal migration is also supported via `migrateBalanceOf`.
|
|
45
86
|
|
|
46
87
|
## Architecture
|
|
47
88
|
|
|
48
89
|
Juicebox V6 separates concerns across specialized contracts that coordinate through a central directory. Projects are represented as ERC-721 NFTs. Each project configures rulesets that dictate how payments, payouts, cash outs, and token minting behave over time.
|
|
49
90
|
|
|
91
|
+
All contracts use Solidity `0.8.26`.
|
|
92
|
+
|
|
50
93
|
### Core Contracts
|
|
51
94
|
|
|
52
95
|
| Contract | Description |
|
|
53
96
|
|----------|-------------|
|
|
54
|
-
| `JBProjects` | ERC-721 registry of projects. Minting an NFT creates a project. |
|
|
55
|
-
| `JBPermissions` | Bitmap-based permission system. Accounts grant operators specific permissions scoped to project IDs. |
|
|
56
|
-
| `JBDirectory` | Maps each project to its controller and terminals. Entry point for looking up where to interact with a project. |
|
|
57
|
-
| `JBController` | Coordinates rulesets, tokens, splits, and fund access limits. Entry point for launching projects,
|
|
58
|
-
| `JBMultiTerminal` | Accepts payments (native ETH and ERC-20s), processes cash outs, distributes payouts,
|
|
59
|
-
| `JBTerminalStore` | Bookkeeping engine for all terminal inflows and outflows. Tracks balances, enforces payout limits and surplus allowances,
|
|
97
|
+
| `JBProjects` | ERC-721 registry of projects. Minting an NFT creates a project. Optionally mints project #1 to a fee beneficiary owner. |
|
|
98
|
+
| `JBPermissions` | Bitmap-based permission system. Accounts grant operators specific permissions scoped to project IDs. Supports ROOT (255) for all-permissions and wildcard project ID (0). |
|
|
99
|
+
| `JBDirectory` | Maps each project to its controller and terminals. Entry point for looking up where to interact with a project. Manages an allowlist of addresses permitted to set a project's first controller. |
|
|
100
|
+
| `JBController` | Coordinates rulesets, tokens, splits, and fund access limits. Entry point for launching projects, queuing rulesets, minting/burning tokens, deploying ERC-20s, sending reserved tokens, setting project URIs, adding price feeds, and transferring credits. |
|
|
101
|
+
| `JBMultiTerminal` | Accepts payments (native ETH and ERC-20s), processes cash outs, distributes payouts, manages surplus allowances, and handles fees. Integrates with Permit2 for ERC-20 approvals. |
|
|
102
|
+
| `JBTerminalStore` | Bookkeeping engine for all terminal inflows and outflows. Tracks balances, enforces payout limits and surplus allowances, computes cash out reclaim amounts via a bonding curve, and integrates with data hooks. |
|
|
60
103
|
| `JBRulesets` | Stores and manages project rulesets. Handles queuing, cycling, weight decay, approval hook validation, and weight caching for long-running projects. |
|
|
61
|
-
| `JBTokens` | Manages dual-balance token accounting (credits + ERC-20). Credits are minted by default; once an ERC-20 is deployed, credits can be claimed as tokens. |
|
|
62
|
-
| `JBSplits` | Stores split configurations per project, ruleset, and group. Splits route percentages of payouts or reserved tokens to beneficiaries, projects, or hooks. |
|
|
63
|
-
| `JBFundAccessLimits` | Stores payout limits and surplus allowances per project, ruleset, terminal, and token. Limits are denominated in configurable currencies. |
|
|
64
|
-
| `JBPrices` | Price feed registry. Maps currency pairs to `IJBPriceFeed` implementations, with per-project overrides and protocol-wide defaults. |
|
|
104
|
+
| `JBTokens` | Manages dual-balance token accounting (credits + ERC-20). Credits are minted by default; once an ERC-20 is deployed or set, credits can be claimed as tokens. Credits are burned before ERC-20 tokens. |
|
|
105
|
+
| `JBSplits` | Stores split configurations per project, ruleset, and group. Splits route percentages of payouts or reserved tokens to beneficiaries, projects, or hooks. Packed storage for gas efficiency. Falls back to ruleset ID 0 if no splits are set for a specific ruleset. |
|
|
106
|
+
| `JBFundAccessLimits` | Stores payout limits and surplus allowances per project, ruleset, terminal, and token. Limits are denominated in configurable currencies and must be set in strictly increasing currency order to prevent duplicates. |
|
|
107
|
+
| `JBPrices` | Price feed registry. Maps currency pairs to `IJBPriceFeed` implementations, with per-project overrides and protocol-wide defaults. Feeds are immutable once set. Inverse prices are auto-calculated. |
|
|
65
108
|
|
|
66
|
-
### Token
|
|
109
|
+
### Token and Price Feed Contracts
|
|
67
110
|
|
|
68
111
|
| Contract | Description |
|
|
69
112
|
|----------|-------------|
|
|
70
|
-
| `JBERC20` | Cloneable ERC-20 with ERC20Votes and ERC20Permit. Deployed by `JBTokens`
|
|
71
|
-
| `JBChainlinkV3PriceFeed` | `IJBPriceFeed` backed by a Chainlink `AggregatorV3Interface` with staleness
|
|
72
|
-
| `JBChainlinkV3SequencerPriceFeed` | Extends `JBChainlinkV3PriceFeed` with L2 sequencer uptime validation for Optimism/Arbitrum. |
|
|
73
|
-
| `JBMatchingPriceFeed` | Returns 1:1 price (e.g
|
|
113
|
+
| `JBERC20` | Cloneable ERC-20 with ERC20Votes and ERC20Permit. Deployed by `JBTokens` via `Clones.clone()`. Owned by `JBTokens`. |
|
|
114
|
+
| `JBChainlinkV3PriceFeed` | `IJBPriceFeed` backed by a Chainlink `AggregatorV3Interface` with staleness threshold. Rejects negative/zero prices and incomplete rounds. |
|
|
115
|
+
| `JBChainlinkV3SequencerPriceFeed` | Extends `JBChainlinkV3PriceFeed` with L2 sequencer uptime validation and grace period for Optimism/Arbitrum. |
|
|
116
|
+
| `JBMatchingPriceFeed` | Returns 1:1 price (e.g., ETH/NATIVE_TOKEN on applicable chains). Lives in `src/periphery/`. |
|
|
74
117
|
|
|
75
118
|
### Utility Contracts
|
|
76
119
|
|
|
77
120
|
| Contract | Description |
|
|
78
121
|
|----------|-------------|
|
|
79
|
-
| `JBFeelessAddresses` | Owner-managed allowlist of addresses exempt from terminal fees. |
|
|
122
|
+
| `JBFeelessAddresses` | Owner-managed allowlist of addresses exempt from terminal fees. Supports `IERC165`. |
|
|
80
123
|
| `JBDeadline` | Approval hook that rejects rulesets queued too close to the current ruleset's end. Ships as `JBDeadline3Hours`, `JBDeadline1Day`, `JBDeadline3Days`, `JBDeadline7Days`. |
|
|
81
124
|
|
|
125
|
+
### Abstract Contracts
|
|
126
|
+
|
|
127
|
+
| Contract | Description |
|
|
128
|
+
|----------|-------------|
|
|
129
|
+
| `JBControlled` | Provides `onlyControllerOf(projectId)` modifier. Used by `JBRulesets`, `JBTokens`, `JBSplits`, `JBFundAccessLimits`, and `JBPrices`. |
|
|
130
|
+
| `JBPermissioned` | Provides `_requirePermissionFrom` and `_requirePermissionAllowingOverrideFrom` helpers. Used by `JBController`, `JBMultiTerminal`, `JBDirectory`, and `JBPrices`. |
|
|
131
|
+
|
|
82
132
|
### Libraries
|
|
83
133
|
|
|
84
134
|
| Library | Description |
|
|
@@ -86,12 +136,22 @@ Juicebox V6 separates concerns across specialized contracts that coordinate thro
|
|
|
86
136
|
| `JBConstants` | Protocol-wide constants: `NATIVE_TOKEN` address, max percentages, max fee. |
|
|
87
137
|
| `JBCurrencyIds` | Currency identifiers (`ETH = 1`, `USD = 2`). |
|
|
88
138
|
| `JBSplitGroupIds` | Group identifiers (`RESERVED_TOKENS = 1`). |
|
|
89
|
-
| `JBCashOuts` | Bonding curve math for computing cash out reclaim amounts. |
|
|
90
|
-
| `JBSurplus` | Calculates a project's surplus across terminals. |
|
|
91
|
-
| `JBFees` | Fee calculation helpers. |
|
|
92
|
-
| `JBFixedPointNumber` | Decimal adjustment
|
|
93
|
-
| `JBMetadataResolver` | Packs and unpacks metadata
|
|
94
|
-
| `JBRulesetMetadataResolver` | Packs and unpacks the `uint256 metadata` field on `JBRuleset` into `JBRulesetMetadata`. |
|
|
139
|
+
| `JBCashOuts` | Bonding curve math for computing cash out reclaim amounts. Includes `minCashOutCountFor` inverse via binary search. |
|
|
140
|
+
| `JBSurplus` | Calculates a project's surplus across all terminals. |
|
|
141
|
+
| `JBFees` | Fee calculation helpers. `feeAmountFrom` (forward) and `feeAmountResultingIn` (backward). |
|
|
142
|
+
| `JBFixedPointNumber` | Decimal adjustment between fixed-point number precisions. |
|
|
143
|
+
| `JBMetadataResolver` | Packs and unpacks variable-length `{id: data}` metadata entries with a lookup table. Used by pay/cash-out hooks. |
|
|
144
|
+
| `JBRulesetMetadataResolver` | Packs and unpacks the `uint256 metadata` field on `JBRuleset` into `JBRulesetMetadata`. Bit layout: version (4 bits), reservedPercent (16), cashOutTaxRate (16), baseCurrency (32), 14 boolean flags (1 bit each), dataHook address (160), metadata (14). |
|
|
145
|
+
|
|
146
|
+
### Hook Interfaces
|
|
147
|
+
|
|
148
|
+
| Interface | Description |
|
|
149
|
+
|-----------|-------------|
|
|
150
|
+
| `IJBRulesetApprovalHook` | Determines whether the next queued ruleset is approved or rejected. Must implement `approvalStatusOf` and `DURATION`. |
|
|
151
|
+
| `IJBRulesetDataHook` | Overrides payment/cash-out parameters. Implements `beforePayRecordedWith`, `beforeCashOutRecordedWith`, and `hasMintPermissionFor`. |
|
|
152
|
+
| `IJBPayHook` | Called after a payment is recorded. Implements `afterPayRecordedWith`. |
|
|
153
|
+
| `IJBCashOutHook` | Called after a cash out is recorded. Implements `afterCashOutRecordedWith`. |
|
|
154
|
+
| `IJBSplitHook` | Called when processing a split. Implements `processSplitWith`. |
|
|
95
155
|
|
|
96
156
|
## Install
|
|
97
157
|
|
package/SKILLS.md
CHANGED
|
@@ -12,44 +12,137 @@ The core Juicebox V6 protocol on EVM: a modular system for launching treasury-ba
|
|
|
12
12
|
| `JBPermissions` | Packed `uint256` bitmap permissions. Operators get specific permission IDs scoped to projects. |
|
|
13
13
|
| `JBDirectory` | Maps project IDs to their controller (`IERC165`) and terminals (`IJBTerminal[]`). |
|
|
14
14
|
| `JBController` | Orchestrates rulesets, tokens, splits, fund access limits. Entry point for project lifecycle. |
|
|
15
|
-
| `JBMultiTerminal` | Handles ETH/ERC-20 payments, cash outs, payouts, surplus allowance, fees. |
|
|
15
|
+
| `JBMultiTerminal` | Handles ETH/ERC-20 payments, cash outs, payouts, surplus allowance, fees. Permit2 integration. |
|
|
16
16
|
| `JBTerminalStore` | Bookkeeping: balances, payout limit tracking, surplus calculation, bonding curve reclaim math. |
|
|
17
17
|
| `JBRulesets` | Stores/cycles rulesets with weight decay, approval hooks, and weight cache for gas-efficient long-running cycles. |
|
|
18
18
|
| `JBTokens` | Dual-balance system: credits (internal) + ERC-20. Credits burned first on burn. |
|
|
19
19
|
| `JBSplits` | Split configurations per project/ruleset/group. Packed storage for gas efficiency. |
|
|
20
20
|
| `JBFundAccessLimits` | Payout limits and surplus allowances per project/ruleset/terminal/token. |
|
|
21
|
-
| `JBPrices` | Price feed registry with project-specific and protocol-wide default feeds. |
|
|
22
|
-
| `JBERC20` | Cloneable ERC-20 with Votes + Permit. Owned by `JBTokens`. |
|
|
21
|
+
| `JBPrices` | Price feed registry with project-specific and protocol-wide default feeds. Immutable once set. |
|
|
22
|
+
| `JBERC20` | Cloneable ERC-20 with Votes + Permit. Owned by `JBTokens`. Deployed via `Clones.clone()`. |
|
|
23
23
|
| `JBFeelessAddresses` | Allowlist for fee-exempt addresses. |
|
|
24
|
-
| `JBChainlinkV3PriceFeed` | Chainlink AggregatorV3 price feed with staleness threshold. |
|
|
25
|
-
| `JBChainlinkV3SequencerPriceFeed` | L2 sequencer-aware Chainlink feed (Optimism/Arbitrum). |
|
|
26
|
-
| `JBDeadline` | Approval hook: rejects rulesets queued within `DURATION` seconds of start. |
|
|
27
|
-
| `JBMatchingPriceFeed` | Always returns 1:1. For equivalent currencies. |
|
|
24
|
+
| `JBChainlinkV3PriceFeed` | Chainlink AggregatorV3 price feed with staleness threshold. Rejects negative/zero prices. |
|
|
25
|
+
| `JBChainlinkV3SequencerPriceFeed` | L2 sequencer-aware Chainlink feed (Optimism/Arbitrum) with grace period after restart. |
|
|
26
|
+
| `JBDeadline` | Approval hook: rejects rulesets queued within `DURATION` seconds of start. Ships as `JBDeadline3Hours`, `JBDeadline1Day`, `JBDeadline3Days`, `JBDeadline7Days`. |
|
|
27
|
+
| `JBMatchingPriceFeed` | Always returns 1:1. For equivalent currencies (e.g. ETH/NATIVE_TOKEN). |
|
|
28
28
|
|
|
29
29
|
## Key Functions
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
|
34
|
-
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
48
|
-
| `
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
31
|
+
### JBController
|
|
32
|
+
|
|
33
|
+
| Function | What it does |
|
|
34
|
+
|----------|--------------|
|
|
35
|
+
| `launchProjectFor(address owner, string uri, JBRulesetConfig[] rulesetConfigs, JBTerminalConfig[] terminalConfigs, string memo)` | Creates a project, queues its first rulesets, and configures terminals. Returns `projectId`. |
|
|
36
|
+
| `launchRulesetsFor(uint256 projectId, JBRulesetConfig[] rulesetConfigs, JBTerminalConfig[] terminalConfigs, string memo)` | Launches the first rulesets for an existing project that has none. |
|
|
37
|
+
| `queueRulesetsOf(uint256 projectId, JBRulesetConfig[] rulesetConfigs, string memo)` | Queues new rulesets for a project. Takes effect after the current ruleset ends (or immediately if duration is 0). |
|
|
38
|
+
| `mintTokensOf(uint256 projectId, uint256 tokenCount, address beneficiary, string memo, bool useReservedPercent)` | Mints project tokens. Requires `allowOwnerMinting` in the current ruleset or caller must be a terminal/hook with mint permission. |
|
|
39
|
+
| `burnTokensOf(address holder, uint256 projectId, uint256 tokenCount, string memo)` | Burns tokens from a holder. Requires holder's permission (`BURN_TOKENS`). |
|
|
40
|
+
| `sendReservedTokensToSplitsOf(uint256 projectId)` | Distributes accumulated reserved tokens to the reserved token split group. Returns token count sent. |
|
|
41
|
+
| `deployERC20For(uint256 projectId, string name, string symbol, bytes32 salt)` | Deploys a cloneable `JBERC20` for the project. Credits become claimable. |
|
|
42
|
+
| `claimTokensFor(address holder, uint256 projectId, uint256 count, address beneficiary)` | Redeems credits for ERC-20 tokens into beneficiary's wallet. |
|
|
43
|
+
| `setSplitGroupsOf(uint256 projectId, uint256 rulesetId, JBSplitGroup[] splitGroups)` | Sets the split groups for a project's ruleset. |
|
|
44
|
+
| `setTokenFor(uint256 projectId, IJBToken token)` | Sets an existing ERC-20 token for the project (requires `allowSetCustomToken` in ruleset). |
|
|
45
|
+
| `setUriOf(uint256 projectId, string uri)` | Sets the project's metadata URI. |
|
|
46
|
+
| `transferCreditsFrom(address holder, uint256 projectId, address recipient, uint256 creditCount)` | Transfers credits between addresses (reverts if `pauseCreditTransfers` is set in ruleset). |
|
|
47
|
+
| `addPriceFeedFor(uint256 projectId, uint256 pricingCurrency, uint256 unitCurrency, IJBPriceFeed feed)` | Registers a price feed (requires `allowAddPriceFeed` in ruleset). |
|
|
48
|
+
| `migrateController(uint256 projectId, IJBMigratable to)` | Migrates the project to a new controller. Calls `beforeReceiveMigrationFrom`, `migrate`, updates directory, then `afterReceiveMigrationFrom`. |
|
|
49
|
+
| `currentRulesetOf(uint256 projectId)` | Returns the current ruleset and unpacked metadata. |
|
|
50
|
+
| `upcomingRulesetOf(uint256 projectId)` | Returns the upcoming ruleset and unpacked metadata. |
|
|
51
|
+
| `allRulesetsOf(uint256 projectId, uint256 startingId, uint256 size)` | Returns an array of rulesets with metadata, paginated. |
|
|
52
|
+
| `pendingReservedTokenBalanceOf(uint256 projectId)` | Returns accumulated reserved tokens not yet distributed. |
|
|
53
|
+
| `totalTokenSupplyWithReservedTokensOf(uint256 projectId)` | Returns total supply including pending reserved tokens. |
|
|
54
|
+
|
|
55
|
+
### JBMultiTerminal
|
|
56
|
+
|
|
57
|
+
| Function | What it does |
|
|
58
|
+
|----------|--------------|
|
|
59
|
+
| `pay(uint256 projectId, address token, uint256 amount, address beneficiary, uint256 minReturnedTokens, string memo, bytes metadata)` | Pays a project. Mints project tokens to beneficiary based on ruleset weight. Returns token count. |
|
|
60
|
+
| `cashOutTokensOf(address holder, uint256 projectId, uint256 cashOutCount, address tokenToReclaim, uint256 minTokensReclaimed, address beneficiary, bytes metadata)` | Burns project tokens and reclaims surplus terminal tokens via bonding curve. |
|
|
61
|
+
| `sendPayoutsOf(uint256 projectId, address token, uint256 amount, uint256 currency, uint256 minTokensPaidOut)` | Distributes payouts from the project's balance to its payout split group, up to the payout limit. |
|
|
62
|
+
| `useAllowanceOf(uint256 projectId, address token, uint256 amount, uint256 currency, uint256 minTokensPaidOut, address payable beneficiary, address payable feeBeneficiary, string memo)` | Withdraws from the project's surplus allowance to a beneficiary. The `feeBeneficiary` receives tokens minted by the fee payment. |
|
|
63
|
+
| `addToBalanceOf(uint256 projectId, address token, uint256 amount, bool shouldReturnHeldFees, string memo, bytes metadata)` | Adds funds to a project's balance without minting tokens. Can unlock held fees. |
|
|
64
|
+
| `migrateBalanceOf(uint256 projectId, address token, IJBTerminal to)` | Migrates a project's token balance to another terminal. Requires `allowTerminalMigration`. |
|
|
65
|
+
| `processHeldFeesOf(uint256 projectId, address token, uint256 count)` | Processes up to `count` held fees for a project, sending them to the fee beneficiary project. |
|
|
66
|
+
| `addAccountingContextsFor(uint256 projectId, JBAccountingContext[] accountingContexts)` | Adds new accounting contexts (token types) to a terminal for a project. |
|
|
67
|
+
| `currentSurplusOf(uint256 projectId, JBAccountingContext[] accountingContexts, uint256 decimals, uint256 currency)` | Returns the project's current surplus in the specified currency. |
|
|
68
|
+
| `accountingContextForTokenOf(uint256 projectId, address token)` | Returns the accounting context for a specific token. |
|
|
69
|
+
| `accountingContextsOf(uint256 projectId)` | Returns all accounting contexts for a project. |
|
|
70
|
+
| `heldFeesOf(uint256 projectId, address token, uint256 count)` | Returns up to `count` held fees for a project/token. |
|
|
71
|
+
|
|
72
|
+
### JBTerminalStore
|
|
73
|
+
|
|
74
|
+
| Function | What it does |
|
|
75
|
+
|----------|--------------|
|
|
76
|
+
| `recordPaymentFrom(address payer, JBTokenAmount amount, uint256 projectId, address beneficiary, bytes metadata)` | Records a payment. Applies data hook if enabled. Returns ruleset, token count, hook specifications. |
|
|
77
|
+
| `recordPayoutFor(uint256 projectId, JBAccountingContext accountingContext, uint256 amount, uint256 currency)` | Records a payout. Enforces payout limits. Returns ruleset and amount paid out. |
|
|
78
|
+
| `recordCashOutFor(address holder, uint256 projectId, uint256 cashOutCount, JBAccountingContext accountingContext, JBAccountingContext[] balanceAccountingContexts, bytes metadata)` | Records a cash out. Computes reclaim via bonding curve. Returns ruleset, reclaim amount, tax rate, and hook specifications. |
|
|
79
|
+
| `recordUsedAllowanceOf(uint256 projectId, JBAccountingContext accountingContext, uint256 amount, uint256 currency)` | Records surplus allowance usage. Enforces allowance limits. Returns ruleset and used amount. |
|
|
80
|
+
| `recordAddedBalanceFor(uint256 projectId, address token, uint256 amount)` | Records funds added to a project's balance. |
|
|
81
|
+
| `recordTerminalMigration(uint256 projectId, address token)` | Records a terminal migration, returning the full balance. |
|
|
82
|
+
| `balanceOf(address terminal, uint256 projectId, address token)` | Returns the balance of a project at a terminal for a given token. |
|
|
83
|
+
| `usedPayoutLimitOf(address terminal, uint256 projectId, address token, uint256 rulesetCycleNumber, uint256 currency)` | Returns the used payout limit for a project in a given cycle. |
|
|
84
|
+
| `usedSurplusAllowanceOf(address terminal, uint256 projectId, address token, uint256 rulesetId, uint256 currency)` | Returns the used surplus allowance for a project in a given ruleset. |
|
|
85
|
+
| `currentSurplusOf(address terminal, uint256 projectId, JBAccountingContext[] accountingContexts, uint256 decimals, uint256 currency)` | Returns the current surplus for a project at a terminal. |
|
|
86
|
+
|
|
87
|
+
### JBRulesets
|
|
88
|
+
|
|
89
|
+
| Function | What it does |
|
|
90
|
+
|----------|--------------|
|
|
91
|
+
| `currentOf(uint256 projectId)` | Returns the currently active ruleset with decayed weight and correct cycle number. |
|
|
92
|
+
| `latestQueuedOf(uint256 projectId)` | Returns the latest queued ruleset and its approval status. |
|
|
93
|
+
| `queueFor(uint256 projectId, uint256 duration, uint256 weight, uint256 weightCutPercent, IJBRulesetApprovalHook approvalHook, uint256 metadata, uint256 mustStartAtOrAfter)` | Queues a new ruleset. Only callable by the project's controller. |
|
|
94
|
+
| `updateRulesetWeightCache(uint256 projectId)` | Updates the weight cache for long-running rulesets. Required when `weightCutMultiple > 20,000` to avoid gas limits. |
|
|
95
|
+
|
|
96
|
+
### JBPermissions
|
|
97
|
+
|
|
98
|
+
| Function | What it does |
|
|
99
|
+
|----------|--------------|
|
|
100
|
+
| `setPermissionsFor(address account, JBPermissionsData permissionsData)` | Grants or revokes operator permissions. ROOT operators can set non-ROOT permissions for others. |
|
|
101
|
+
| `hasPermission(address operator, address account, uint256 projectId, uint256 permissionId)` | Checks if an operator has a specific permission. |
|
|
102
|
+
| `hasPermissions(address operator, address account, uint256 projectId, uint256[] permissionIds)` | Checks if an operator has all specified permissions. |
|
|
103
|
+
|
|
104
|
+
### JBDirectory
|
|
105
|
+
|
|
106
|
+
| Function | What it does |
|
|
107
|
+
|----------|--------------|
|
|
108
|
+
| `controllerOf(uint256 projectId)` | Returns the project's controller as `IERC165`. |
|
|
109
|
+
| `terminalsOf(uint256 projectId)` | Returns the project's terminals as `IJBTerminal[]`. |
|
|
110
|
+
| `primaryTerminalOf(uint256 projectId, address token)` | Returns the project's primary terminal for a given token. |
|
|
111
|
+
| `isTerminalOf(uint256 projectId, IJBTerminal terminal)` | Checks if a terminal belongs to a project. |
|
|
112
|
+
| `setControllerOf(uint256 projectId, IERC165 controller)` | Sets the project's controller. |
|
|
113
|
+
| `setTerminalsOf(uint256 projectId, IJBTerminal[] terminals)` | Sets the project's terminals. |
|
|
114
|
+
| `setPrimaryTerminalOf(uint256 projectId, address token, IJBTerminal terminal)` | Sets the primary terminal for a token. |
|
|
115
|
+
| `setIsAllowedToSetFirstController(address addr, bool flag)` | Allows/disallows an address to set a project's first controller. Owner-only. |
|
|
116
|
+
|
|
117
|
+
### JBPrices
|
|
118
|
+
|
|
119
|
+
| Function | What it does |
|
|
120
|
+
|----------|--------------|
|
|
121
|
+
| `pricePerUnitOf(uint256 projectId, uint256 pricingCurrency, uint256 unitCurrency, uint256 decimals)` | Returns the price of 1 `unitCurrency` in `pricingCurrency`. Checks project-specific, inverse, then default feeds. |
|
|
122
|
+
| `addPriceFeedFor(uint256 projectId, uint256 pricingCurrency, uint256 unitCurrency, IJBPriceFeed feed)` | Registers a price feed. Project ID 0 sets protocol-wide defaults (owner-only). Immutable once set. |
|
|
123
|
+
|
|
124
|
+
### JBTokens
|
|
125
|
+
|
|
126
|
+
| Function | What it does |
|
|
127
|
+
|----------|--------------|
|
|
128
|
+
| `totalSupplyOf(uint256 projectId)` | Returns total supply: credits + ERC-20 tokens. |
|
|
129
|
+
| `totalBalanceOf(address holder, uint256 projectId)` | Returns combined credit + ERC-20 balance. |
|
|
130
|
+
| `creditBalanceOf(address holder, uint256 projectId)` | Returns the holder's credit balance. |
|
|
131
|
+
| `tokenOf(uint256 projectId)` | Returns the ERC-20 token for a project (`IJBToken`). |
|
|
132
|
+
|
|
133
|
+
### JBSplits
|
|
134
|
+
|
|
135
|
+
| Function | What it does |
|
|
136
|
+
|----------|--------------|
|
|
137
|
+
| `splitsOf(uint256 projectId, uint256 rulesetId, uint256 groupId)` | Returns splits for a project/ruleset/group. Falls back to ruleset ID 0 if none set. |
|
|
138
|
+
|
|
139
|
+
### Other
|
|
140
|
+
|
|
141
|
+
| Function | What it does |
|
|
142
|
+
|----------|--------------|
|
|
143
|
+
| `setFeelessAddress(address addr, bool flag)` | Adds or removes an address from the fee exemption list. Owner-only. (`JBFeelessAddresses`) |
|
|
144
|
+
| `setControllerAllowed(uint256 projectId)` | Returns whether a project's controller can currently be set. (`IJBDirectoryAccessControl`) |
|
|
145
|
+
| `setTerminalsAllowed(uint256 projectId)` | Returns whether a project's terminals can currently be set. (`IJBDirectoryAccessControl`) |
|
|
53
146
|
|
|
54
147
|
## Key Types
|
|
55
148
|
|
|
@@ -69,8 +162,21 @@ The core Juicebox V6 protocol on EVM: a modular system for launching treasury-ba
|
|
|
69
162
|
| `JBFee` | `amount (uint256)`, `beneficiary (address)`, `unlockTimestamp (uint48)` | Held fees in `JBMultiTerminal` |
|
|
70
163
|
| `JBSingleAllowance` | `sigDeadline (uint256)`, `amount (uint160)`, `expiration (uint48)`, `nonce (uint48)`, `signature (bytes)` | Permit2 allowance in terminal payments |
|
|
71
164
|
| `JBRulesetWithMetadata` | `ruleset (JBRuleset)`, `metadata (JBRulesetMetadata)` | `allRulesetsOf()`, `currentRulesetOf()` return values |
|
|
165
|
+
| `JBRulesetWeightCache` | `weight (uint112)`, `weightCutMultiple (uint168)` | Weight caching for long-running rulesets in `JBRulesets` |
|
|
72
166
|
| `JBApprovalStatus` (enum) | `Empty`, `Upcoming`, `Active`, `ApprovalExpected`, `Approved`, `Failed` | Approval hook status for queued rulesets |
|
|
73
167
|
|
|
168
|
+
### Hook Structs
|
|
169
|
+
|
|
170
|
+
| Struct | Key Fields | Used In |
|
|
171
|
+
|--------|------------|---------|
|
|
172
|
+
| `JBBeforePayRecordedContext` | `terminal`, `payer`, `amount (JBTokenAmount)`, `projectId`, `rulesetId`, `beneficiary`, `weight`, `reservedPercent`, `metadata` | `IJBRulesetDataHook.beforePayRecordedWith()` input |
|
|
173
|
+
| `JBBeforeCashOutRecordedContext` | `terminal`, `holder`, `projectId`, `rulesetId`, `cashOutCount`, `totalSupply`, `surplus (JBTokenAmount)`, `useTotalSurplus`, `cashOutTaxRate`, `metadata` | `IJBRulesetDataHook.beforeCashOutRecordedWith()` input |
|
|
174
|
+
| `JBAfterPayRecordedContext` | `payer`, `projectId`, `rulesetId`, `amount (JBTokenAmount)`, `forwardedAmount (JBTokenAmount)`, `weight`, `newlyIssuedTokenCount`, `beneficiary`, `hookMetadata`, `payerMetadata` | `IJBPayHook.afterPayRecordedWith()` input |
|
|
175
|
+
| `JBAfterCashOutRecordedContext` | `holder`, `projectId`, `rulesetId`, `cashOutCount`, `reclaimedAmount (JBTokenAmount)`, `forwardedAmount (JBTokenAmount)`, `cashOutTaxRate`, `beneficiary`, `hookMetadata`, `cashOutMetadata` | `IJBCashOutHook.afterCashOutRecordedWith()` input |
|
|
176
|
+
| `JBPayHookSpecification` | `hook (IJBPayHook)`, `amount`, `metadata` | Returned by data hook; specifies which pay hooks to call and how much to forward |
|
|
177
|
+
| `JBCashOutHookSpecification` | `hook (IJBCashOutHook)`, `amount`, `metadata` | Returned by data hook; specifies which cash out hooks to call and how much to forward |
|
|
178
|
+
| `JBSplitHookContext` | `token`, `amount`, `decimals`, `projectId`, `groupId`, `split (JBSplit)` | `IJBSplitHook.processSplitWith()` input |
|
|
179
|
+
|
|
74
180
|
### Constants (`JBConstants`)
|
|
75
181
|
|
|
76
182
|
| Constant | Value | Meaning |
|
|
@@ -89,6 +195,24 @@ The core Juicebox V6 protocol on EVM: a modular system for launching treasury-ba
|
|
|
89
195
|
| `1` | ETH |
|
|
90
196
|
| `2` | USD |
|
|
91
197
|
|
|
198
|
+
### Split Group IDs (`JBSplitGroupIds`)
|
|
199
|
+
|
|
200
|
+
| ID | Group |
|
|
201
|
+
|----|-------|
|
|
202
|
+
| `1` | `RESERVED_TOKENS` -- reserved token distribution |
|
|
203
|
+
|
|
204
|
+
### Special Values
|
|
205
|
+
|
|
206
|
+
| Value | Context | Meaning |
|
|
207
|
+
|-------|---------|---------|
|
|
208
|
+
| `weight = 0` | `JBRuleset` / `JBRulesetConfig` | No token issuance for payments. |
|
|
209
|
+
| `weight = 1` | `JBRuleset` / `JBRulesetConfig` | Inherit decayed weight from previous ruleset (sentinel). |
|
|
210
|
+
| `duration = 0` | `JBRuleset` / `JBRulesetConfig` | Ruleset never expires; must be explicitly replaced by a new queued ruleset (takes effect immediately). |
|
|
211
|
+
| `projectId = 0` | `JBPermissionsData` | Wildcard: permission applies to ALL projects. Cannot be combined with ROOT (255). |
|
|
212
|
+
| `permissionId = 255` | `JBPermissions` | ROOT: grants all permissions for the scoped project. |
|
|
213
|
+
| `rulesetId = 0` | `JBSplits.splitsOf()` | Fallback split group used when no splits are set for a specific ruleset. |
|
|
214
|
+
| `projectId = 0` | `JBPrices.addPriceFeedFor()` | Sets a protocol-wide default price feed (owner-only). |
|
|
215
|
+
|
|
92
216
|
## Gotchas
|
|
93
217
|
|
|
94
218
|
- `IJBDirectory.controllerOf()` returns `IERC165`, NOT `address` -- must wrap: `address(directory.controllerOf(projectId))`
|
|
@@ -110,12 +234,24 @@ The core Juicebox V6 protocol on EVM: a modular system for launching treasury-ba
|
|
|
110
234
|
- `JBProjects` constructor optionally mints project #1 to `feeProjectOwner` -- if `address(0)`, no fee project is created
|
|
111
235
|
- `JBMultiTerminal` derives `DIRECTORY` and `RULESETS` from the provided `store` in its constructor -- not passed directly
|
|
112
236
|
- `JBPrices.pricePerUnitOf()` checks project-specific feed, then inverse, then falls back to `DEFAULT_PROJECT_ID = 0`
|
|
237
|
+
- `useAllowanceOf()` takes 8 args including `address payable feeBeneficiary` -- do NOT omit it
|
|
238
|
+
- Cash out tax rate of 0% = proportional (1:1) redemption; 100% = nothing reclaimable (all surplus locked). Do NOT confuse with a "cash out rate" where 100% means full redemption.
|
|
239
|
+
- `cashOutTaxRate` in `JBRulesetMetadata` is `uint16` (max 10,000 basis points), NOT 9-decimal precision
|
|
240
|
+
- `reservedPercent` in `JBRulesetMetadata` is `uint16` (max 10,000 basis points), NOT 9-decimal precision
|
|
241
|
+
- `weight` in `JBRuleset` is `uint112`, but `weight` in `JBRulesetConfig` is also `uint112` -- both use 18 decimals
|
|
242
|
+
- `JBSplits.splitsOf()` falls back to ruleset ID 0 if no splits are set for the given rulesetId
|
|
243
|
+
- Held fees are held for 28 days (`_FEE_HOLDING_SECONDS = 2,419,200`) before they can be processed
|
|
244
|
+
- `JBController`, `JBMultiTerminal`, `JBProjects`, `JBPrices`, `JBPermissions` all support ERC-2771 meta-transactions
|
|
245
|
+
- `JBRulesetMetadataResolver` bit layout: version (4 bits), reservedPercent (16), cashOutTaxRate (16), baseCurrency (32), 14 boolean flags (1 bit each), dataHook address (160), metadata (14)
|
|
246
|
+
- `IJBDirectoryAccessControl` has `setControllerAllowed()` and `setTerminalsAllowed()` -- NOT `setControllerAllowedFor()`
|
|
247
|
+
- Price feeds are immutable once set in `JBPrices` -- they cannot be replaced or removed
|
|
248
|
+
- `JBFundAccessLimits` requires payout limits and surplus allowances to be in strictly increasing currency order to prevent duplicates
|
|
113
249
|
|
|
114
250
|
## Example Integration
|
|
115
251
|
|
|
116
252
|
```solidity
|
|
117
253
|
// SPDX-License-Identifier: MIT
|
|
118
|
-
pragma solidity 0.8.
|
|
254
|
+
pragma solidity 0.8.26;
|
|
119
255
|
|
|
120
256
|
import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol";
|
|
121
257
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
package/foundry.toml
CHANGED
package/package.json
CHANGED
package/script/Deploy.s.sol
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.
|
|
2
|
+
pragma solidity 0.8.26;
|
|
3
3
|
|
|
4
4
|
import {AggregatorV2V3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV2V3Interface.sol";
|
|
5
5
|
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";
|
package/src/JBController.sol
CHANGED
package/src/JBDeadline.sol
CHANGED
package/src/JBDirectory.sol
CHANGED
package/src/JBERC20.sol
CHANGED
package/src/JBMultiTerminal.sol
CHANGED
package/src/JBPermissions.sol
CHANGED
package/src/JBPrices.sol
CHANGED
package/src/JBProjects.sol
CHANGED
package/src/JBRulesets.sol
CHANGED
package/src/JBSplits.sol
CHANGED