Basics
Workflows
The first transaction to call when getting started is JBController3_1.launchProjectFor(...)
.
function launchProjectFor(
address _owner,
JBProjectMetadata calldata _projectMetadata,
JBFundingCycleData calldata _data,
JBFundingCycleMetadata calldata _metadata,
uint256 _mustStartAtOrAfter,
JBGroupedSplits[] calldata _groupedSplits,
JBFundAccessConstraints[] calldata _fundAccessConstraints,
IJBPaymentTerminal[] calldata _terminals,
string memory _memo
) external override returns (uint256 projectId) { ... }
Check out the Treasury design page for more info on how to build projects treasuries to various specifications.
View project info
Launching a project will mint a new NFT in the JBProjects
contract. The owner can be found using JBProjects.ownerOf(...)
.
function ownerOf(uint256 _projectId) external returns (address owner) { ... }
The project's metadata can be found using JBProjects.metadataContentOf(...)
.
function metadataContentOf(uint256 _projectId, uint256 _domain)
external
view
returns (string memory) { ... }
View funding cycles
Funding cycle data can be found in the JBFundingCycleStore
contract. A funding cycle configuration can be found using JBFundingCycleStore.get(...)
, where _configuration
is the block timestamp when the funding cycle was configured, or using JBController3_1.getFundingCycleOf(...)
if the funding cycle's metadata is needed alongside.
function get(uint256 _projectId, uint256 _configuration)
external
view
override
returns (JBFundingCycle memory fundingCycle) { ... }
function getFundingCycleOf(uint256 _projectId, uint256 _configuration)
external
view
override
returns (JBFundingCycle memory fundingCycle, JBFundingCycleMetadata memory metadata) { ... }
The project's current funding cycle can be found using JBFundingCycleStore.currentOf(...)
, or using JBController3_1.currentFundingCycleOf(...)
if the funding cycle's metadata is needed alongside.
function currentOf(uint256 _projectId)
external
view
override
returns (JBFundingCycle memory fundingCycle) { ... }
function currentFundingCycleOf(uint256 _projectId)
external
view
override
returns (JBFundingCycle memory fundingCycle, JBFundingCycleMetadata memory metadata) { ... }
The project's queued funding cycle can be found using JBFundingCycleStore.queuedOf(...)
, or using JBController3_1.queuedFundingCycleOf(...)
if the funding cycle's metadata is needed alongside.
By default, the queued cycle is a copy of the current one that starts immediately afterwards, using a discounted weight.
If the project has proposed a reconfiguration, the queued cycle will reflect the changes once they are approved by the current cycle's ballot. Reconfigurations during a funding cycle with no ballot are automatically queued.
The project has no queued cycle if the current cycle has no duration.
function queuedOf(uint256 _projectId)
external
view
override
returns (JBFundingCycle memory fundingCycle) { ... }
function queuedFundingCycleOf(uint256 _projectId)
external
view
override
returns (JBFundingCycle memory fundingCycle, JBFundingCycleMetadata memory metadata) { ... }
The project's latest configured funding cycle can be found using JBFundingCycleStore.latestConfiguredOf(...)
, or using JBController3_1.latestConfiguredFundingCycleOf(...)
if the funding cycle's metadata is needed alongside. These calls also return the current ballot status for the configuration.
If the latest configured funding cycle's ballot is Approved
, the configuration should also be queued or current.
function latestConfiguredOf(uint256 _projectId)
external
view
override
returns (JBFundingCycle memory fundingCycle, JBBallotState ballotState) { ... }
function latestConfiguredFundingCycleOf(uint256 _projectId)
external
view
override
returns (
JBFundingCycle memory fundingCycle,
JBFundingCycleMetadata memory metadata,
JBBallotState ballotState
) { ... }
View splits
A project's splits data can be found in the JBSplitStore
contract. A group of splits belonging to any particular group during any particular funding cycle configuration can be found using JBSplitStore.splitsOf(...)
. The funding cycle's configuration is used as the _domain
within which the splits apply.
function splitsOf(
uint256 _projectId,
uint256 _domain,
uint256 _group
) external view override returns (JBSplit[] memory) { ... }
View fund access constraints
Constraints on accessing a project's funds can found in the JBFundAccessConstraintsStore
contract associated with the JBController3_1
contract used to launch the project. You can find the JBFundAccessConstraintsStore
contract by calling JBController3_1.fundAccessConstraintsStore
. The distribution limit of any payment terminal during any funding cycle configuration can be found using JBFundAccessConstraintsStore.distributionLimitOf(...)
. The currency being used for this distribution limit is returned alongside.
function distributionLimitOf(
uint256 _projectId,
uint256 _configuration,
IJBPaymentTerminal _terminal,
address _token
) external view override returns (uint256, uint256);
The overflow allowance from any payment terminal during any funding cycle configuration can be found using JBFundAccessConstraintsStore.overflowAllowanceOf
. The currency being used for this overflow allowance is returned alongside.
function overflowAllowanceOf(
uint256 _projectId,
uint256 _configuration,
IJBPaymentTerminal _terminal,
address _token
) external view override returns (uint256, uint256);
View terminals and controller
The JBDirectory
contract stores addresses of payment terminals that a project is currently accepting funds through. A project's currently set terminals can be found using JBDirectory.terminalsOf(...)
.
function terminalsOf(uint256 _projectId) external view override returns (IJBPaymentTerminal[] memory) { ... }
If a project has multiple terminals for the same token, the primary terminal that it wishes to accept that token type through can be found using JBDirectory.primaryTerminalOf(...)
.
function primaryTerminalOf(uint256 _projectId, address _token)
public
view
override
returns (IJBPaymentTerminal) { ... }
The JBDirectory
contract also stores the address of the controller that is managing a project's funding cycles and tokens. A projects current terminal can be found using JBDirectory.controllerOf(...)
.
function controllerOf(uint256 _projectId) external view override returns (IJBController3_1) { ... }
Once a project has been created, it can begin accepting funds from anyone through any terminal it has added. For example, if the project has added the JBETHPaymentTerminal3_1_1
, ETH can be sent to the project by calling its JBETHPaymentTerminal3_1_1.pay(...)
transaction.
function pay(
uint256 _projectId,
uint256 _amount,
address,
address _beneficiary,
uint256 _minReturnedTokens,
bool _preferClaimedTokens,
string calldata _memo,
bytes calldata _metadata
) external payable virtual override isTerminalOf(_projectId) returns (uint256) { ... }
View treasury balance
In payment terminals based on the JBPayoutRedemptionPaymentTerminal3_1_1
, such as JBETHPaymentTerminal3_1_1
's and JBERC20PaymentTerminal3_1_1
's, a project's treasury balance can be found in its store contract. For example, in the JBSingleTokenPaymentTerminalStore3_1_1
, the balance can be found using JBSingleTokenPaymentTerminalStore3_1_1.balanceOf(...)
.
function balanceOf(IJBPaymentTerminal _terminal, uint256 _projectId)
external
view
override
returns (uint256) { ... }
The project's current overflow for a terminal can also be found in the store contracts. For example, in the JBSingleTokenPaymentTerminalStore3_1_1
, the terminal's overflow can be found using JBSingleTokenPaymentTerminalStore3_1_1.currentOverflowOf(...)
.
function currentOverflowOf(IJBSingleTokenPaymentTerminal _terminal, uint256 _projectId)
external
view
override
returns (uint256) { ... }
A terminal store can also resolve the total amount of overflow in all of a project's terminals. For example, in the JBSingleTokenPaymentTerminalStore3_1_1
, the project's overall overflow can be found using JBSingleTokenPaymentTerminalStore3_1_1.currentTotalOverflowOf(...)
. You will need to send the number of decimals you're expecting the returned fixed point number to include, and the currency it is in terms of.
function currentTotalOverflowOf(
uint256 _projectId,
uint256 _decimals,
uint256 _currency
) external view override returns (uint256) { ... }
View project token distribution
Each holder's balance of a project's token can be found in the JBTokenStore
contract. The balance can be found using JBTokenStore.balanceOf(...)
.
function balanceOf(address _holder, uint256 _projectId) external view returns (uint256 _result) { ... }
The project token's total supply can also be found in the JBTokenStore
contract using JBTokenStore.totalSupplyOf(...)
function totalSupplyOf(uint256 _projectId) external view returns (uint256) { ... }
View reserved token balance
A project's undistributed reserved token balance can be found in the project's current controller. For example in the JBController3_1
, this balance can be found using JBController3_1.reservedTokenBalanceOf(...)
.
function reservedTokenBalanceOf(uint256 _projectId, uint256 _reservedRate)
external
view
returns (uint256) { ... }
For projects using JBController3_1
, the project token's total supply including any allocated reserved tokens that have yet to be distributed can be found in using JBController3_1.totalOutstandingTokensOf(...)
.
function totalOutstandingTokensOf(uint256 _projectId, uint256 _reservedRate)
external
view
override
returns (uint256) { ... }
Anyone can distribute a project's funds from a terminal up to its current funding cycle's distribution limit to its preprogrammed payout splits at any time. For example, if the project has added the JBETHPaymentTerminal3_1_1
, funds can be distributed by calling JBETHPaymentTerminal3_1_1.distributePayoutsOf(...)
.
function distributePayoutsOf(
uint256 _projectId,
uint256 _amount,
uint256 _currency,
uint256 _minReturnedTokens,
string calldata _memo
) external virtual override returns (uint256 netLeftoverDistributionAmount) { ... }