Skip to main content

REVDeployer

Git Source

Inherits: ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCashOutHook, IERC721Receiver

REVDeployer deploys, manages, and operates Revnets.

Revnets are unowned Juicebox projects which operate autonomously after deployment.

State Variables

CASH_OUT_DELAY

The number of seconds until a revnet's participants can cash out, starting from the time when that revnet is deployed to a new network.

  • Only applies to existing revnets which are deploying onto a new network.
  • To prevent liquidity/arbitrage issues which might arise when an existing revnet adds a brand-new treasury.

30 days, in seconds.

uint256 public constant override CASH_OUT_DELAY = 2_592_000;

FEE

The cash out fee (as a fraction out of JBConstants.MAX_FEE). Cashout fees are paid to the revnet with the FEE_REVNET_ID.

Fees are charged on cashouts if the cash out tax rate is greater than 0%.

When suckers withdraw funds, they do not pay cash out fees.

uint256 public constant override FEE = 25;

CONTROLLER

The controller used to create and manage Juicebox projects for revnets.

IJBController public immutable override CONTROLLER;

DIRECTORY

The directory of terminals and controllers for Juicebox projects (and revnets).

IJBDirectory public immutable override DIRECTORY;

FEE_REVNET_ID

The Juicebox project ID of the revnet that receives cash out fees.

uint256 public immutable override FEE_REVNET_ID;

HOOK_DEPLOYER

Deploys tiered ERC-721 hooks for revnets.

IJB721TiersHookDeployer public immutable override HOOK_DEPLOYER;

PERMISSIONS

Stores Juicebox project (and revnet) access permissions.

IJBPermissions public immutable override PERMISSIONS;

PROJECTS

Mints ERC-721s that represent Juicebox project (and revnet) ownership and transfers.

IJBProjects public immutable override PROJECTS;

PUBLISHER

Manages the publishing of ERC-721 posts to revnet's tiered ERC-721 hooks.

CTPublisher public immutable override PUBLISHER;

SUCKER_REGISTRY

Deploys and tracks suckers for revnets.

IJBSuckerRegistry public immutable override SUCKER_REGISTRY;

amountToAutoIssue

The number of revnet tokens which can be "auto-minted" (minted without payments) for a specific beneficiary during a stage. Think of this as a per-stage premint.

These tokens can be minted with autoIssueFor(…).

mapping(uint256 revnetId => mapping(uint256 stageId => mapping(address beneficiary => uint256))) public override
amountToAutoIssue;

buybackHookOf

Each revnet's buyback data hook. These return buyback hook data.

Buyback hooks are a combined data hook/pay hook.

mapping(uint256 revnetId => IJBRulesetDataHook buybackHook) public override buybackHookOf;

cashOutDelayOf

The timestamp of when cashouts will become available to a specific revnet's participants.

Only applies to existing revnets which are deploying onto a new network.

mapping(uint256 revnetId => uint256 cashOutDelay) public override cashOutDelayOf;

hashedEncodedConfigurationOf

The hashed encoded configuration of each revnet.

This is used to ensure that the encoded configuration of a revnet is the same when deploying suckers for omnichain operations.

mapping(uint256 revnetId => bytes32 hashedEncodedConfiguration) public override hashedEncodedConfigurationOf;

loansOf

Each revnet's loan contract.

Revnets can offer loans to their participants, collateralized by their tokens. Participants can borrow up to the current cash out value of their tokens.

mapping(uint256 revnetId => address) public override loansOf;

tiered721HookOf

Each revnet's tiered ERC-721 hook.

mapping(uint256 revnetId => IJB721TiersHook tiered721Hook) public override tiered721HookOf;

_extraOperatorPermissions

A list of JBPermissonIds indices to grant to the split operator of a specific revnet.

These should be set in the revnet's deployment process.

mapping(uint256 revnetId => uint256[]) internal _extraOperatorPermissions;

Functions

constructor

constructor(
IJBController controller,
IJBSuckerRegistry suckerRegistry,
uint256 feeRevnetId,
IJB721TiersHookDeployer hookDeployer,
CTPublisher publisher,
address trustedForwarder
)
ERC2771Context(trustedForwarder);

Parameters

NameTypeDescription
controllerIJBControllerThe controller to use for launching and operating the Juicebox projects which will be revnets.
suckerRegistryIJBSuckerRegistryThe registry to use for deploying and tracking each revnet's suckers.
feeRevnetIduint256The Juicebox project ID of the revnet that will receive fees.
hookDeployerIJB721TiersHookDeployerThe deployer to use for revnet's tiered ERC-721 hooks.
publisherCTPublisherThe croptop publisher revnets can use to publish ERC-721 posts to their tiered ERC-721 hooks.
trustedForwarderaddressThe trusted forwarder for the ERC2771Context.

beforePayRecordedWith

Before a revnet processes an incoming payment, determine the weight and pay hooks to use.

This function is part of IJBRulesetDataHook, and gets called before the revnet processes a payment.

function beforePayRecordedWith(JBBeforePayRecordedContext calldata context)
external
view
override
returns (uint256 weight, JBPayHookSpecification[] memory hookSpecifications);

Parameters

NameTypeDescription
contextJBBeforePayRecordedContextStandard Juicebox payment context. See JBBeforePayRecordedContext.

Returns

NameTypeDescription
weightuint256The weight which revnet tokens are minted relative to. This can be used to customize how many tokens get minted by a payment.
hookSpecificationsJBPayHookSpecification[]Amounts (out of what's being paid in) to be sent to pay hooks instead of being paid into the revnet. Useful for automatically routing funds from a treasury as payments come in.

beforeCashOutRecordedWith

Determine how a cash out from a revnet should be processed.

This function is part of IJBRulesetDataHook, and gets called before the revnet processes a cash out.

If a sucker is cashing out, no taxes or fees are imposed.

function beforeCashOutRecordedWith(JBBeforeCashOutRecordedContext calldata context)
external
view
override
returns (
uint256 cashOutTaxRate,
uint256 cashOutCount,
uint256 totalSupply,
JBCashOutHookSpecification[] memory hookSpecifications
);

Parameters

NameTypeDescription
contextJBBeforeCashOutRecordedContextStandard Juicebox cash out context. See JBBeforeCashOutRecordedContext.

Returns

NameTypeDescription
cashOutTaxRateuint256The cash out tax rate, which influences the amount of terminal tokens which get cashed out.
cashOutCountuint256The number of revnet tokens that are cashed out.
totalSupplyuint256The total revnet token supply.
hookSpecificationsJBCashOutHookSpecification[]The amount of funds and the data to send to cash out hooks (this contract).

hasMintPermissionFor

A flag indicating whether an address has permission to mint a revnet's tokens on-demand.

Required by the IJBRulesetDataHook interface.

function hasMintPermissionFor(uint256 revnetId, address addr) external view override returns (bool);

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to check permissions for.
addraddressThe address to check the mint permission of.

Returns

NameTypeDescription
<none>boolflag A flag indicating whether the address has permission to mint the revnet's tokens on-demand.

onERC721Received

Make sure this contract can only receive project NFTs from JBProjects.

function onERC721Received(address, address, uint256, bytes calldata) external view returns (bytes4);

isSplitOperatorOf

A flag indicating whether an address is a revnet's split operator.

function isSplitOperatorOf(uint256 revnetId, address addr) public view override returns (bool);

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet.
addraddressThe address to check.

Returns

NameTypeDescription
<none>boolflag A flag indicating whether the address is the revnet's split operator.

supportsInterface

Indicates if this contract adheres to the specified interface.

See IERC165.supportsInterface.

function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool);

Returns

NameTypeDescription
<none>boolA flag indicating if the provided interface ID is supported.

_checkIfIsSplitOperatorOf

If the specified address is not the revnet's current split operator, revert.

function _checkIfIsSplitOperatorOf(uint256 revnetId, address operator) internal view;

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to check split operator status for.
operatoraddressThe address being checked.

_isSuckerOf

A flag indicating whether an address is a revnet's sucker.

function _isSuckerOf(uint256 revnetId, address addr) internal view returns (bool);

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to check sucker status for.
addraddressThe address being checked.

Returns

NameTypeDescription
<none>boolisSucker A flag indicating whether the address is one of the revnet's suckers.

_makeLoanFundAccessLimits

Initialize a fund access limit group for the loan contract to use.

Returns an unlimited surplus allowance for each token which can be loaned out.

function _makeLoanFundAccessLimits(
REVConfig calldata configuration,
JBTerminalConfig[] calldata terminalConfigurations
)
internal
pure
returns (JBFundAccessLimitGroup[] memory fundAccessLimitGroups);

Parameters

NameTypeDescription
configurationREVConfigThe revnet's configuration.
terminalConfigurationsJBTerminalConfig[]The terminals to set up for the revnet. Used for payments and cash outs.

Returns

NameTypeDescription
fundAccessLimitGroupsJBFundAccessLimitGroup[]The fund access limit groups for the loans.

_makeRulesetConfiguration

Make a ruleset configuration for a revnet's stage.

function _makeRulesetConfiguration(
uint32 baseCurrency,
REVStageConfig calldata stageConfiguration,
JBFundAccessLimitGroup[] memory fundAccessLimitGroups
)
internal
view
returns (JBRulesetConfig memory);

Parameters

NameTypeDescription
baseCurrencyuint32The base currency of the revnet.
stageConfigurationREVStageConfigThe stage configuration to make a ruleset for.
fundAccessLimitGroupsJBFundAccessLimitGroup[]The fund access limit groups to set up for the ruleset.

Returns

NameTypeDescription
<none>JBRulesetConfigrulesetConfiguration The ruleset configuration.

_matchingCurrencyOf

Returns the currency of the loan source, if a matching terminal configuration is found.

function _matchingCurrencyOf(
JBTerminalConfig[] calldata terminalConfigurations,
REVLoanSource calldata loanSource
)
internal
pure
returns (uint32);

Parameters

NameTypeDescription
terminalConfigurationsJBTerminalConfig[]The terminals to check.
loanSourceREVLoanSourceThe loan source to check.

Returns

NameTypeDescription
<none>uint32currency The currency of the loan source.

_splitOperatorPermissionIndexesOf

Returns the permissions that the split operator should be granted for a revnet.

function _splitOperatorPermissionIndexesOf(uint256 revnetId)
internal
view
returns (uint256[] memory allOperatorPermissions);

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to get split operator permissions for.

Returns

NameTypeDescription
allOperatorPermissionsuint256[]The permissions that the split operator should be granted for the revnet, including both default and custom permissions.

afterCashOutRecordedWith

Processes the fee from a cash out.

function afterCashOutRecordedWith(JBAfterCashOutRecordedContext calldata context) external payable;

Parameters

NameTypeDescription
contextJBAfterCashOutRecordedContextCash out context passed in by the terminal.

autoIssueFor

Auto-mint a revnet's tokens from a stage for a beneficiary.

function autoIssueFor(uint256 revnetId, uint256 stageId, address beneficiary) external override;

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to auto-mint tokens from.
stageIduint256The ID of the stage auto-mint tokens are available from.
beneficiaryaddressThe address to auto-mint tokens to.

deployFor

Launch a revnet, or convert an existing Juicebox project into a revnet.

function deployFor(
uint256 revnetId,
REVConfig calldata configuration,
JBTerminalConfig[] calldata terminalConfigurations,
REVBuybackHookConfig calldata buybackHookConfiguration,
REVSuckerDeploymentConfig calldata suckerDeploymentConfiguration
)
external
override
returns (uint256);

Parameters

NameTypeDescription
revnetIduint256The ID of the Juicebox project to turn into a revnet. Send 0 to deploy a new revnet.
configurationREVConfigCore revnet configuration. See REVConfig.
terminalConfigurationsJBTerminalConfig[]The terminals to set up for the revnet. Used for payments and cash outs.
buybackHookConfigurationREVBuybackHookConfigThe buyback hook and pools to set up for the revnet. The buyback hook buys tokens from a Uniswap pool if minting new tokens would be more expensive.
suckerDeploymentConfigurationREVSuckerDeploymentConfigThe suckers to set up for the revnet. Suckers facilitate cross-chain token transfers between peer revnets on different networks.

Returns

NameTypeDescription
<none>uint256revnetId The ID of the newly created revnet.

deploySuckersFor

Deploy new suckers for an existing revnet.

Only the revnet's split operator can deploy new suckers.

function deploySuckersFor(
uint256 revnetId,
REVSuckerDeploymentConfig calldata suckerDeploymentConfiguration
)
external
override
returns (address[] memory suckers);

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to deploy suckers for. See _makeRulesetConfigurations(…) for encoding details. Clients can read the encoded configuration from the DeployRevnet event emitted by this contract.
suckerDeploymentConfigurationREVSuckerDeploymentConfigThe suckers to set up for the revnet.

deployWith721sFor

Launch a revnet which sells tiered ERC-721s and (optionally) allows croptop posts to its ERC-721 tiers.

function deployWith721sFor(
uint256 revnetId,
REVConfig calldata configuration,
JBTerminalConfig[] calldata terminalConfigurations,
REVBuybackHookConfig calldata buybackHookConfiguration,
REVSuckerDeploymentConfig calldata suckerDeploymentConfiguration,
REVDeploy721TiersHookConfig calldata tiered721HookConfiguration,
REVCroptopAllowedPost[] calldata allowedPosts
)
external
override
returns (uint256, IJB721TiersHook hook);

Parameters

NameTypeDescription
revnetIduint256The ID of the Juicebox project to turn into a revnet. Send 0 to deploy a new revnet.
configurationREVConfigCore revnet configuration. See REVConfig.
terminalConfigurationsJBTerminalConfig[]The terminals to set up for the revnet. Used for payments and cash outs.
buybackHookConfigurationREVBuybackHookConfigThe buyback hook and pools to set up for the revnet. The buyback hook buys tokens from a Uniswap pool if minting new tokens would be more expensive.
suckerDeploymentConfigurationREVSuckerDeploymentConfigThe suckers to set up for the revnet. Suckers facilitate cross-chain token transfers between peer revnets on different networks.
tiered721HookConfigurationREVDeploy721TiersHookConfigHow to set up the tiered ERC-721 hook for the revnet.
allowedPostsREVCroptopAllowedPost[]Restrictions on which croptop posts are allowed on the revnet's ERC-721 tiers.

Returns

NameTypeDescription
<none>uint256revnetId The ID of the newly created revnet.
hookIJB721TiersHookThe address of the tiered ERC-721 hook that was deployed for the revnet.

setSplitOperatorOf

Change a revnet's split operator.

Only a revnet's current split operator can set a new split operator.

function setSplitOperatorOf(uint256 revnetId, address newSplitOperator) external override;

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to set the split operator of.
newSplitOperatoraddressThe new split operator's address.

_beforeTransferTo

Logic to be triggered before transferring tokens from this contract.

function _beforeTransferTo(address to, address token, uint256 amount) internal returns (uint256);

Parameters

NameTypeDescription
toaddressThe address the transfer is going to.
tokenaddressThe token being transferred.
amountuint256The number of tokens being transferred, as a fixed point number with the same number of decimals as the token specifies.

Returns

NameTypeDescription
<none>uint256payValue The value to attach to the transaction being sent.

_configurePostingCriteriaFor

Configure croptop posting.

function _configurePostingCriteriaFor(
address hook,
REVCroptopAllowedPost[] calldata allowedPosts
)
internal
returns (bool);

Parameters

NameTypeDescription
hookaddressThe hook that will be posted to.
allowedPostsREVCroptopAllowedPost[]The type of posts that the revent should allow.

Returns

NameTypeDescription
<none>boolflag A flag indicating if posts were configured. Returns false if there were no posts to set up.

_deploy721RevnetFor

Deploy a revnet which sells tiered ERC-721s and (optionally) allows croptop posts to its ERC-721 tiers.

function _deploy721RevnetFor(
uint256 revnetId,
bool shouldDeployNewRevnet,
REVConfig calldata configuration,
JBTerminalConfig[] calldata terminalConfigurations,
REVBuybackHookConfig calldata buybackHookConfiguration,
REVSuckerDeploymentConfig calldata suckerDeploymentConfiguration,
REVDeploy721TiersHookConfig calldata tiered721HookConfiguration,
REVCroptopAllowedPost[] calldata allowedPosts
)
internal
returns (IJB721TiersHook hook);

Parameters

NameTypeDescription
revnetIduint256The ID of the Juicebox project to turn into a revnet. Send 0 to deploy a new revnet.
shouldDeployNewRevnetboolWhether to deploy a new revnet or convert an existing Juicebox project into a revnet.
configurationREVConfigCore revnet configuration. See REVConfig.
terminalConfigurationsJBTerminalConfig[]The terminals to set up for the revnet. Used for payments and cash outs.
buybackHookConfigurationREVBuybackHookConfigThe buyback hook and pools to set up for the revnet. The buyback hook buys tokens from a Uniswap pool if minting new tokens would be more expensive.
suckerDeploymentConfigurationREVSuckerDeploymentConfigThe suckers to set up for the revnet. Suckers facilitate cross-chain token transfers between peer revnets on different networks.
tiered721HookConfigurationREVDeploy721TiersHookConfigHow to set up the tiered ERC-721 hook for the revnet.
allowedPostsREVCroptopAllowedPost[]Restrictions on which croptop posts are allowed on the revnet's ERC-721 tiers.

Returns

NameTypeDescription
hookIJB721TiersHookThe address of the tiered ERC-721 hook that was deployed for the revnet.

_deployRevnetFor

Deploy a revnet, or convert an existing Juicebox project into a revnet.

function _deployRevnetFor(
uint256 revnetId,
bool shouldDeployNewRevnet,
REVConfig calldata configuration,
JBTerminalConfig[] calldata terminalConfigurations,
REVBuybackHookConfig calldata buybackHookConfiguration,
REVSuckerDeploymentConfig calldata suckerDeploymentConfiguration,
JBRulesetConfig[] memory rulesetConfigurations,
bytes32 encodedConfigurationHash
)
internal;

Parameters

NameTypeDescription
revnetIduint256The ID of the Juicebox project to turn into a revnet. Send 0 to deploy a new revnet.
shouldDeployNewRevnetboolWhether to deploy a new revnet or convert an existing Juicebox project into a revnet.
configurationREVConfigCore revnet configuration. See REVConfig.
terminalConfigurationsJBTerminalConfig[]The terminals to set up for the revnet. Used for payments and cash outs.
buybackHookConfigurationREVBuybackHookConfigThe buyback hook and pools to set up for the revnet. The buyback hook buys tokens from a Uniswap pool if minting new tokens would be more expensive.
suckerDeploymentConfigurationREVSuckerDeploymentConfigThe suckers to set up for the revnet. Suckers facilitate cross-chain token transfers between peer revnets on different networks.
rulesetConfigurationsJBRulesetConfig[]The rulesets to set up for the revnet.
encodedConfigurationHashbytes32A hash that represents the revnet's configuration. See _makeRulesetConfigurations(…) for encoding details. Clients can read the encoded configuration from the DeployRevnet event emitted by this contract.

_deploySuckersFor

Deploy suckers for a revnet.

function _deploySuckersFor(
uint256 revnetId,
bytes32 encodedConfigurationHash,
REVSuckerDeploymentConfig calldata suckerDeploymentConfiguration
)
internal
returns (address[] memory suckers);

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to deploy suckers for.
encodedConfigurationHashbytes32A hash that represents the revnet's configuration. See _makeRulesetConfigurations(…) for encoding details. Clients can read the encoded configuration from the DeployRevnet event emitted by this contract.
suckerDeploymentConfigurationREVSuckerDeploymentConfigThe suckers to set up for the revnet.

_makeRulesetConfigurations

Convert a revnet's stages into a series of Juicebox project rulesets.

function _makeRulesetConfigurations(
uint256 revnetId,
REVConfig calldata configuration,
JBTerminalConfig[] calldata terminalConfigurations
)
internal
returns (JBRulesetConfig[] memory rulesetConfigurations, bytes32 encodedConfigurationHash);

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to make rulesets for.
configurationREVConfigThe configuration containing the revnet's stages.
terminalConfigurationsJBTerminalConfig[]The terminals to set up for the revnet. Used for payments and cash outs.

Returns

NameTypeDescription
rulesetConfigurationsJBRulesetConfig[]A list of ruleset configurations defined by the stages.
encodedConfigurationHashbytes32A hash that represents the revnet's configuration. Used for sucker deployment salts.

_mintTokensOf

Mints a revnet's tokens.

function _mintTokensOf(uint256 revnetId, uint256 tokenCount, address beneficiary) internal;

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to mint tokens for.
tokenCountuint256The number of tokens to mint.
beneficiaryaddressThe address to send the tokens to.

_setCashOutDelayIfNeeded

Sets the cash out delay if the revnet's stages are already in progress.

This prevents cash out liquidity/arbitrage issues for existing revnets which are deploying to a new chain.

function _setCashOutDelayIfNeeded(uint256 revnetId, REVStageConfig calldata firstStageConfig) internal;

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to set the cash out delay for.
firstStageConfigREVStageConfigThe revnet's first stage.

_setPermission

Grants a permission to an address (an "operator").

function _setPermission(address operator, uint256 revnetId, uint8 permissionId) internal;

Parameters

NameTypeDescription
operatoraddressThe address to give the permission to.
revnetIduint256The ID of the revnet to scope the permission for.
permissionIduint8The ID of the permission to set. See JBPermissionIds.

_setPermissionsFor

Grants a permission to an address (an "operator").

function _setPermissionsFor(
address account,
address operator,
uint256 revnetId,
uint8[] memory permissionIds
)
internal;

Parameters

NameTypeDescription
accountaddressThe account granting the permission.
operatoraddressThe address to give the permission to.
revnetIduint256The ID of the revnet to scope the permission for.
permissionIdsuint8[]An array of permission IDs to set. See JBPermissionIds.

_setSplitOperatorOf

Give a split operator their permissions.

Only a revnet's current split operator can set a new split operator, by calling setSplitOperatorOf(…).

function _setSplitOperatorOf(uint256 revnetId, address operator) internal;

Parameters

NameTypeDescription
revnetIduint256The ID of the revnet to set the split operator of.
operatoraddressThe new split operator's address.

Errors

REVDeployer_LoanSourceDoesntMatchTerminalConfigurations

error REVDeployer_LoanSourceDoesntMatchTerminalConfigurations(address token, address terminal);

REVDeployer_AutoIssuanceBeneficiaryZeroAddress

error REVDeployer_AutoIssuanceBeneficiaryZeroAddress();

REVDeployer_CashOutDelayNotFinished

error REVDeployer_CashOutDelayNotFinished(uint256 cashOutDelay, uint256 blockTimestamp);

REVDeployer_CashOutsCantBeTurnedOffCompletely

error REVDeployer_CashOutsCantBeTurnedOffCompletely(uint256 cashOutTaxRate, uint256 maxCashOutTaxRate);

REVDeployer_MustHaveSplits

error REVDeployer_MustHaveSplits();

REVDeployer_RulesetDoesNotAllowDeployingSuckers

error REVDeployer_RulesetDoesNotAllowDeployingSuckers();

REVDeployer_StageNotStarted

error REVDeployer_StageNotStarted(uint256 stageStartTime, uint256 blockTimestamp);

REVDeployer_StagesRequired

error REVDeployer_StagesRequired();

REVDeployer_StageTimesMustIncrease

error REVDeployer_StageTimesMustIncrease();

REVDeployer_Unauthorized

error REVDeployer_Unauthorized(uint256 revnetId, address caller);