Skip to main content

Contract Examples

Simple contract examples which integrate with Juicebox. If you're building new Juicebox-related contracts, join our Discord server for help!

Pay

A simple contract which pays a project through their primary ETH terminal.

import '@jbx-protocol/juice-contracts-v3/contracts/interfaces/IJBDirectory.sol';
import '@jbx-protocol/juice-contracts-v3/contracts/libraries/JBTokens.sol';

contract MyBangarangApp {
// Keep a reference to the directory in which project's current payment terminal's can be found.
IJBDirectory directory;

// Keep a reference to the project ID that'll be paid.
uint256 projectId;

constructor(IJBDirectory _directory, uint256 _projectId) {
directory = _directory;
projectId = _projectId;
}

function doSomething() external payable {
// Get the payment terminal the project currently prefers to accept ETH through.
IJBPaymentTerminal _ethTerminal = directory.primaryTerminalOf(projectId, JBTokens.ETH);

_ethTerminal.pay{ value: msg.value }(
projectId, // pay the correct project.
amount, // pay the full amount sent to this function.
JBTokens.ETH, // assert that the payment is being made in ETH.
msg.sender, // send the msg.sender as the beneficiary of any tokens issued from the payment.
0, // if you know the amount of project tokens you expect to be receiving as a result of this payment, specify it here to ensure this happens accordingly. this can be useful if your expectations rely on an oracle calculation. set to 0 if you're ok getting whatever you get.
false, // set this to true if you know the project has issued ERC-20's, and you prefer receiving the ERC-20's directly instead of keeping the option to claim later.
"This is a test payment!!", // send a memo if you want,
bytes(0) // no need to send metadata. if you know the project is using an extension that requires more information to fulfill the operation -- such as NFT minting -- you'll want to add the appropriate formatted metadata here.
});
}
}

Read Balance

A simple contract which reads a project's balance in their primary ETH terminal.

import '@jbx-protocol/juice-contracts-v3/contracts/interfaces/IJBDirectory.sol';
import '@jbx-protocol/juice-contracts-v3/contracts/interfaces/IJBETHPaymentTerminal.sol';
import '@jbx-protocol/juice-contracts-v3/contracts/libraries/JBTokens.sol';

contract JBProjectViewUtil {
// Keep a reference to the directory in which project's current payment terminal's can be found.
IJBDirectory directory;

constructor(IJBDirectory _directory, uint256 _projectId) {
directory = _directory;
}

function getETHBalance(uint256 _projectId) external returns (uint256) {
// Get the payment terminal the project currently prefers to accept ETH through.
IJBPaymentTerminal _ethTerminal = directory.primaryTerminalOf(projectId, JBTokens.ETH);

// Assumes the terminal is a IJBETHPaymentTerminal. If the terminal could be a lesser version, a ERC165 check should be done before casting.
return IJBETHPaymentTerminal(_ethTerminal).store().balanceOf(_ethTerminal, projectId);
}
}

Read Overflow

A simple project which reads a project's overflow in their primary ETH terminal. A project's Overflow is the funds it holds which aren't needed for the current funding cycle's payouts.

import '@jbx-protocol/juice-contracts-v3/contracts/interfaces/IJBDirectory.sol';
import '@jbx-protocol/juice-contracts-v3/contracts/libraries/JBTokens.sol';

contract JBProjectViewUtil {
// Keep a reference to the directory in which project's current payment terminal's can be found.
IJBDirectory directory;

constructor(IJBDirectory _directory, uint256 _projectId) {
directory = _directory;
}

function getETHBalance(uint256 _projectId) external returns (uint256) {
// Get the payment terminal the project currently prefers to accept ETH through.
IJBPaymentTerminal _terminal = directory.primaryTerminalOf(_projectId, JBTokens.ETH);

// Return a project's balance in excess of any commitments already made but not yet distributed.
return _terminal.currentEthOverflowOf(_projectId);
}
}

IJBPaymentTerminals are required to report how much ETH's worth of tokens it holds for a project in excess of funds needed for the current funding cycle's payouts via IJBPaymentTerminal.currentEthOverflowOf(uint256 _projectId). The terminal can be written to assume a conversion rate to ETH of 0, meaning it could have a balance of 10,000 shitcoins but still have an ETH overflow of 0.

This requirement allows for straightforwards calculation of a project's total redeemable balance for use in redemption calculations and custom data sources.