计划执行与检查节点
executing-plans
按既定实施计划完成工作,保持过程检查和反馈。
jb-v5-api【效率与协作】Juicebox V5 protocol API reference. Function signatures, parameters, and return values for all contracts. Use for "what functions exist?" and "what are the signatures?" questions. For internal mechanics and tradeoffs, use /jb-v5-impl instead.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Function signatures, parameters, and return values for the entire Juicebox V5 protocol ecosystem.
Note: For deep implementation details, edge cases, and tradeoffs, use
/jb-v5-implinstead.
The V5 protocol consists of interconnected repositories:
| Repository | Purpose |
|---|---|
| nana-core-v5 | Core infrastructure: projects, rulesets, tokens, terminals |
| nana-suckers-v5 | Cross-chain token bridging via merkle proofs |
| nana-buyback-hook-v5 | Uniswap V3 token buyback integration |
| nana-swap-terminal-v5 | Accept any token, auto-swap to ETH |
| nana-721-hook-v5 | Tiered NFT minting on payment |
| nana-permission-ids-v5 | Permission ID constants |
| nana-ownable-v5 | Juicebox-aware ownership pattern |
| nana-omnichain-deployers-v5 | Multi-chain project deployment |
| revnet-core-v5 | Autonomous tokenized treasury networks |
| croptop-core-v5 | Public NFT posting and contribution |
Core Contracts (State Management):
JBProjects - ERC-721 project ownershipJBRulesets - Time-bounded configuration queuingJBTokens - Credit and ERC-20 accountingJBDirectory - Terminal and controller mappingJBPermissions - Access control delegationJBFundAccessLimits - Withdrawal constraintsJBPrices - Currency price feedsJBSplits - Payment distribution listsSurface Contracts (User Entry Points):
JBController - Ruleset and token coordinationJBMultiTerminal - Payments, cash outs, distributionsJBTerminalStore - Transaction bookkeepingUtility Contracts:
JBDeadline - Ruleset approval with advance noticeJBERC20 - Standard project tokenJBFeelessAddresses - Fee exemption registryJBChainlinkV3PriceFeed - Chainlink integration// Create a new project with initial rulesets
function launchProjectFor(
address owner, // Receives project NFT
string calldata projectUri, // IPFS metadata URI
JBRulesetConfig[] calldata rulesetConfigurations,
JBTerminalConfig[] calldata terminalConfigurations,
string calldata memo
) external returns (uint256 projectId);
// Queue rulesets for existing project (first time setup)
function launchRulesetsFor(
uint256 projectId,
JBRulesetConfig[] calldata rulesetConfigurations,
JBTerminalConfig[] calldata terminalConfigurations,
string calldata memo
) external returns (uint256 rulesetId);
// Add rulesets to end of queue
function queueRulesetsOf(
uint256 projectId,
JBRulesetConfig[] calldata rulesetConfigurations,
string calldata memo
) external returns (uint256 rulesetId);
// Migrate to a different controller
function migrate(uint256 projectId, IERC165 to) external;
// Mint tokens to beneficiary
function mintTokensOf(
uint256 projectId,
uint256 tokenCount,
address beneficiary,
string calldata memo,
bool useReservedPercent // Apply reserved rate?
) external returns (uint256 beneficiaryTokenCount);
// Burn tokens from holder
function burnTokensOf(
address holder,
uint256 projectId,
uint256 tokenCount,
string calldata memo
) external;
// Deploy ERC-20 for project (enables token claiming)
function deployERC20For(
uint256 projectId,
string calldata name,
string calldata symbol,
bytes32 salt // For deterministic address
) external returns (IJBToken token);
// Convert credits to ERC-20 tokens
function claimTokensFor(
address holder,
uint256 projectId,
uint256 tokenCount,
address beneficiary
) external;
// Transfer credits between addresses
function transferCreditsFrom(
address holder,
uint256 projectId,
address recipient,
uint256 creditCount
) external;
// Distribute pending reserved tokens
function sendReservedTokensToSplitsOf(uint256 projectId)
external returns (uint256);
// Update project metadata URI
function setUriOf(uint256 projectId, string calldata uri) external;
// Set project's ERC-20 token
function setTokenFor(uint256 projectId, IJBToken token) external;
// Update split groups
function setSplitGroupsOf(
uint256 projectId,
uint256 rulesetId,
JBSplitGroup[] calldata splitGroups
) external;
// Add price feed for currency conversion
function addPriceFeed(
uint256 projectId,
uint256 pricingCurrency,
uint256 unitCurrency,
IJBPriceFeed feed
) external;
function currentRulesetOf(uint256 projectId)
external view returns (JBRuleset, JBRulesetMetadata);
function upcomingRulesetOf(uint256 projectId)
external view returns (JBRuleset, JBRulesetMetadata);
function latestQueuedRulesetOf(uint256 projectId)
external view returns (JBRuleset, JBRulesetMetadata, JBApprovalStatus);
function getRulesetOf(uint256 projectId, uint256 rulesetId)
external view returns (JBRuleset, JBRulesetMetadata);
function allRulesetsOf(uint256 projectId, uint256 startingId, uint256 size)
external view returns (JBRulesetWithMetadata[]);
function totalTokenSupplyWithReservedTokensOf(uint256 projectId)
external view returns (uint256);
function setTerminalsAllowed(uint256 projectId) external view returns (bool);
function setControllerAllowed(uint256 projectId) external view returns (bool);
Manages project token accounting, including credits (unclaimed balances) and ERC20 tokens.
// Deploy standard JBERC20 for a project
function deployERC20For(
uint256 projectId,
string calldata name,
string calldata symbol,
bytes32 salt // For deterministic address (0 for non-deterministic)
) external returns (IJBToken token);
// Set a custom ERC20 as the project token
function setTokenFor(
uint256 projectId,
IJBToken token // Must implement IJBToken interface
) external;
// Mint tokens to a holder (called by controller)
function mintFor(
address holder,
uint256 projectId,
uint256 count
) external;
// Burn tokens from a holder (called by controller)
function burnFrom(
address holder,
uint256 projectId,
uint256 count
) external;
// Convert credits to ERC20 tokens
function claimTokensFor(
address holder,
uint256 projectId,
uint256 count,
address beneficiary
) external;
// Transfer credits between addresses
function transferCreditsFrom(
address holder,
uint256 projectId,
address recipient,
uint256 count
) external;
// Get the ERC20 token for a project (address(0) if credits-only)
function tokenOf(uint256 projectId) external view returns (IJBToken);
// Get the project ID for a token
function projectIdOf(IJBToken token) external view returns (uint256);
// Get credit balance for a holder
function creditBalanceOf(address holder, uint256 projectId) external view returns (uint256);
// Get total credit supply for a project
function totalCreditSupplyOf(uint256 projectId) external view returns (uint256);
// Get total balance (credits + ERC20) for a holder
function totalBalanceOf(address holder, uint256 projectId) external view returns (uint256);
// Get total supply (credits + ERC20) for a project
function totalSupplyOf(uint256 projectId) external view returns (uint256);
Custom tokens must implement this interface:
interface IJBToken is IERC20 {
// Standard ERC20 functions (name, symbol, decimals, totalSupply, balanceOf, transfer, etc.)
/// @notice Check if this token can be added to a project.
/// @dev Must return true for setTokenFor() to succeed.
function canBeAddedTo(uint256 projectId) external view returns (bool);
/// @notice Mint tokens. Called by JBTokens on payments.
function mint(address holder, uint256 amount) external;
/// @notice Burn tokens. Called by JBTokens on cash outs.
function burn(address holder, uint256 amount) external;
}
| Requirement | Details |
|---|---|
| 18 decimals | decimals() must return 18 |
| canBeAddedTo | Must return true for the target project ID |
| Unique assignment | Cannot be assigned to multiple projects |
| Controller access | Must allow JBController to mint/burn |
// Pay a project
function pay(
uint256 projectId,
address token, // address(0) for native
uint256 amount,
address beneficiary, // Receives minted tokens
uint256 minReturnedTokens, // Slippage protection
string calldata memo,
bytes calldata metadata // Hook data
) external payable returns (uint256 beneficiaryTokenCount);
// Add funds without minting tokens
function addToBalanceOf(
uint256 projectId,
address token,
uint256 amount,
bool shouldReturnHeldFees,
string calldata memo,
bytes calldata metadata
) external payable;
// Cash out tokens for funds
function cashOutTokensOf(
address holder,
uint256 projectId,
uint256 cashOutCount, // Tokens to burn
address tokenToReclaim, // Which token to receive
uint256 minTokensReclaimed, // Slippage protection
address payable beneficiary,
bytes calldata metadata
) external returns (uint256 reclaimAmount);
// Send payouts to splits (within payout limit)
function sendPayoutsOf(
uint256 projectId,
address token,
uint256 amount,
uint256 currency,
uint256 minTokensPaidOut
) external returns (uint256 amountPaidOut);
// Use surplus allowance (discretionary withdrawal)
function useAllowanceOf(
uint256 projectId,
address token,
uint256 amount,
uint256 currency,
uint256 minTokensPaidOut,
address payable beneficiary,
address payable feeBeneficiary,
string calldata memo
) external returns (uint256 netAmountPaidOut);
// Add token accounting contexts
function addAccountingContextsFor(
uint256 projectId,
JBAccountingContext[] calldata accountingContexts
) external;
// Migrate to new terminal
function migrateBalanceOf(
uint256 projectId,
address token,
IJBTerminal to
) external returns (uint256 balance);
// Process held fees
function processHeldFeesOf(
uint256 projectId,
address token,
uint256 count
) external;
function currentSurplusOf(
uint256 projectId,
JBAccountingContext[] memory accountingContexts,
uint256 decimals,
uint256 currency
) external view returns (uint256);
function accountingContextsOf(uint256 projectId)
external view returns (JBAccountingContext[]);
function accountingContextForTokenOf(uint256 projectId, address token)
external view returns (JBAccountingContext);
function heldFeesOf(uint256 projectId, address token, uint256 count)
external view returns (JBFee[]);
Suckers enable cross-chain token transfers between Juicebox projects. When a user burns tokens on one chain, they receive equivalent tokens on another chain. The sucker redeems locally and bridges funds to the peer network.
JBOptimismSucker - Ethereum ↔ OptimismJBBaseSucker - Ethereum ↔ BaseJBArbitrumSucker - Ethereum ↔ Arbitrum// Prepare tokens for bridging (burns locally)
function prepare(
uint256 projectTokenAmount,
address beneficiary,
uint256 minTokensReclaimed,
address tokenToReclaim
) external returns (uint256 terminalTokenAmount);
// Bridge outbox tree to remote chain
function toRemote(address token) external payable;
// Claim tokens on remote chain with merkle proof
function claim(JBClaim[] calldata claims) external;
// Get merkle root for verification
function outboxTreeRoot(address token) external view returns (bytes32);
Automatically routes payments through Uniswap V3 when swapping yields more tokens than direct minting. Acts as both a data hook and pay hook.
beforePayRecordedWith() compares: mint tokens vs. swap tokensafterPayRecordedWith() executes swap, burns received tokens, re-mints with reserved rate// Set Uniswap pool for a project
function setPoolFor(
uint256 projectId,
address token,
uint24 fee,
uint32 twapWindow,
uint256 twapSlippageTolerance
) external;
// Get pool configuration
function poolOf(uint256 projectId, address token)
external view returns (IUniswapV3Pool);
// Data hook: determine payment route
function beforePayRecordedWith(JBBeforePayRecordedContext calldata context)
external view returns (uint256 weight, JBPayHookSpecification[]);
// Pay hook: execute swap if beneficial
function afterPayRecordedWith(JBAfterPayRecordedContext calldata context)
external payable;
Accept payments in any ERC-20 token and automatically swap to ETH/native token via Uniswap V3.
// Pay with any token (auto-swaps to ETH)
function pay(
uint256 projectId,
address token, // Any ERC-20
uint256 amount,
address beneficiary,
uint256 minReturnedTokens,
string calldata memo,
bytes calldata metadata // Can include swap params
) external returns (uint256 beneficiaryTokenCount);
// Configure default Uniswap pool for token
function addDefaultPool(
uint256 projectId,
address token,
IUniswapV3Pool pool
) external;
Mint tiered NFTs (ERC-721) when payments are received. Each tier has configurable price, supply, artwork, and voting power.
// Data hook: specify NFT minting
function beforePayRecordedWith(JBBeforePayRecordedContext calldata context)
external view returns (uint256 weight, JBPayHookSpecification[]);
// Pay hook: mint NFTs based on payment
function afterPayRecordedWith(JBAfterPayRecordedContext calldata context)
external payable;
// Cash out hook: burn NFTs to reclaim funds
function afterCashOutRecordedWith(JBAfterCashOutRecordedContext calldata context)
external payable;
// Get tiers for a hook
function tiersOf(
address hook,
uint256[] calldata categories,
bool includeResolvedUri,
uint256 startingId,
uint256 size
) external view returns (JB721Tier[]);
// Adjust tiers (add/remove)
function adjustTiers(JB721TierConfig[] calldata tierConfigs) external;
// Owner mint from specific tiers
function mintFor(
uint256[] calldata tierIds,
address beneficiary
) external returns (uint256[] tokenIds);
| ID | Name | Allows |
|---|---|---|
| 1 | ROOT | All operations (superuser) |
| 2 | QUEUE_RULESETS | Queue new rulesets |
| 3 | CASH_OUT_TOKENS | Cash out tokens on behalf of holder |
| 4 | SEND_PAYOUTS | Trigger payout distributions |
| 5 | MIGRATE_TERMINAL | Migrate terminal balance |
| 6 | SET_PROJECT_URI | Update project metadata URI |
| 7 | DEPLOY_ERC20 | Deploy ERC-20 token for project |
| 8 | SET_TOKEN | Set project's token |
| 9 | MINT_TOKENS | Mint project tokens |
| 10 | BURN_TOKENS | Burn tokens |
| 11 | CLAIM_TOKENS | Convert credits to ERC-20 |
| 12 | TRANSFER_CREDITS | Transfer credits between addresses |
| 13 | SET_CONTROLLER | Change project controller |
| 14 | SET_TERMINALS | Modify project terminals |
| 15 | SET_PRIMARY_TERMINAL | Set primary terminal for token |
| 16 | USE_ALLOWANCE | Use surplus allowance |
| 17 | SET_SPLIT_GROUPS | Modify split groups |
| 18 | ADD_PRICE_FEED | Add currency price feed |
| 19 | ADD_ACCOUNTING_CONTEXTS | Add token acceptance |
| 20 | ADJUST_721_TIERS | Modify NFT tiers |
| 21 | SET_721_METADATA | Update NFT metadata |
| 22 | MINT_721 | Mint NFTs directly |
| 23 | SET_721_DISCOUNT_PERCENT | Set NFT discount |
| 24 | SET_BUYBACK_TWAP | Configure buyback TWAP |
| 25 | SET_BUYBACK_POOL | Set buyback Uniswap pool |
| 26 | ADD_SWAP_TERMINAL_POOL | Add swap terminal pool |
| 27 | ADD_SWAP_TERMINAL_TWAP_PARAMS | Set swap terminal TWAP |
| 28 | MAP_SUCKER_TOKEN | Map sucker token |
| 29 | DEPLOY_SUCKERS | Deploy cross-chain suckers |
| 30 | SUCKER_SAFETY | Sucker safety operations |
| ID Range | Repository |
|---|---|
| 1 | ROOT (all contracts) |
| 2-19 | nana-core |
| 20-23 | nana-721-hook |
| 24-25 | nana-buyback-hook |
| 26-27 | nana-swap-terminal |
| 28-30 | nana-suckers |
// Grant permissions
function setPermissionsFor(
address account,
JBPermissionsData calldata permissionsData
) external;
// Check permission
function hasPermission(
address operator,
address account,
uint256 projectId,
uint256 permissionId,
bool includeRoot,
bool includeWildcardProjectId
) external view returns (bool);
// Get all permissions for operator
function permissionsOf(
address operator,
address account,
uint256 projectId
) external view returns (uint256);
Extend OpenZeppelin Ownable to support Juicebox project ownership and permission delegation.
onlyOwner access via JBPermissionsJBOwnable - For contracts without existing ownershipJBOwnableOverride - For contracts inheriting OpenZeppelin OwnableDeploy Juicebox projects with suckers across multiple chains in a single transaction.
Deploy project configuration that automatically sets up:
A Revnet is an unowned Juicebox project that operates autonomously after deployment. The deployer contract owns the project NFT, implementing hooks and delegating limited permissions.
| Deployer | Features |
|---|---|
BasicRevnetDeployer | Standard revnet |
PayHookRevnetDeployer | + custom pay hooks |
Tiered721RevnetDeployer | + tiered NFT support |
CroptopRevnetDeployer | + public posting |
Stages: Revnets progress through stages with different parameters
Premint: Tokens minted to beneficiaries at launch
Boost: Temporary increased token allocation for specified recipients
// Deploy a new revnet
function deployFor(
uint256 revnetId,
REVConfig calldata configuration,
JBTerminalConfig[] calldata terminalConfigurations,
REVBuybackHookConfig calldata buybackHookConfiguration,
REVSuckerDeploymentConfig calldata suckerDeploymentConfiguration
) external returns (uint256 projectId);
// Data hook: route payments through buyback
function beforePayRecordedWith(JBBeforePayRecordedContext calldata context)
external view returns (uint256 weight, JBPayHookSpecification[]);
// Cash out hook: extract fees
function afterCashOutRecordedWith(JBAfterCashOutRecordedContext calldata context)
external payable;
Croptop opens a project's NFT collection for public contributions. Anyone can post new NFT tiers if they meet criteria set by the project owner.
// Configure posting criteria
function configurePostingCriteriaFor(
IJB721TiersHook hook,
uint256 category,
uint256 minimumPrice,
uint256 minimumTotalSupply,
uint256 maximumTotalSupply,
address[] calldata allowedAddresses
) external;
// Post new NFT and mint initial copies
function mintFrom(
IJB721TiersHook hook,
JBDeploy721TierConfig[] calldata tierConfigs,
address beneficiary,
address payable feeBeneficiary,
bytes calldata additionalPayMetadata
) external payable;
// Get posting criteria
function allowanceFor(IJB721TiersHook hook, uint256 category)
external view returns (CTAllowedPost);
// Get tier data for URIs
function tiersFor(IJB721TiersHook hook, string[] calldata uris)
external view returns (JB721Tier[]);
configurePostingCriteriaFor() with price/supply requirementsmintFrom() with tier config and paymentApplied by JBMultiTerminal on:
// Native token identifier
address constant NATIVE_TOKEN = 0x000000000000000000000000000000000000EEEe;
// Max values
uint256 constant MAX_RESERVED_RATE = 10000; // 100%
uint256 constant MAX_CASH_OUT_TAX_RATE = 10000; // 100%
uint256 constant MAX_FEE = 250; // 2.5%
// Split percent precision
uint256 constant SPLITS_TOTAL_PERCENT = 1_000_000_000; // 100%
JBBuybackHook for your tokenlaunchProjectFor() with ruleset metadata:
useDataHookForPay: truedataHook: buybackHookAddressdeployFor() with configurationJBSuckerRegistryprepare() on one chain, claim() on other