Skip to main content

14 posts tagged with "protocol"

View All Tags

Cross-layer Juicebox Protocol

· 2 min read
Jango
JuiceboxDAO Contributor

Projects building on Juicebox need payment terminals that cost its contributors less gas to pay and redeem.

To do so, projects need to be able to accept funds across many different L2s alongside mainnet.

The simplest option would be to just deploy the same Juicebox protocol in each EVM compatible L2 environment. This forces projects to choose which they would like to operate on, or manage their own complexity if they would like to operate across many. I'm guessing most projects would prefer to operate everywhere, if only it were easy to do so.

JuiceboxDAO runs on the juicebox protocol itself, if we do nothing at the protocol layer and go with this simple option we will come across the same dilemma. If instead we preemptively consider how we can adjust the Juicebox V2 protocol to make cross layer operation simple for us, we'll likely also be making it simple for all projects who choose to build around juicebox treasuries.

An effective solution will take into consideration that:

  • projects do not want to fragment its community and governance across chains. All members should be cheering for funds to come in from wherever people care to contribute from, and the project's distributed tokens in turn should provide the opportunity to govern its cumulative funds regardless of what chain they're on.
  • the issuance rate of the project's tokens should be synchronizable across all available environments over time. As funding cycles roll over, it's often the case that the weight of token distribution changes. Unless it is by design, there shouldn't be arbitrage opportunities across chains.
  • funding cycle reconfigurations should either be approved or fail across all environments. If a project proposes to reconfigure its funding parameters in one environment but the ballot to do so ends up failing, the change should also fail to take effect in all other environments. On the flip side, successful funding cycle reconfigurations should be reflected across chains.

Stay tuned for specific proposals from me of how this might be achieve across rollup L2s, and please contribute to the conversation with your own ideas so we can arrive at the best possible set of solutions together.

JuiceboxV2 Protocol

· 11 min read
Jango
JuiceboxDAO Contributor

Current state of things

First thing's first: a huge thank you to everyone who has played with the first version of the Juicebox protocol over the past month. You've taken a leap of faith on a very experimental and untested set of contracts and user experiences with the hopes that it would help you smoothly realize your vision. The protocol has helped a number of projects bootstrap their treasury and community, and these communities have in turn helped Juicebox root into the fertile soil that is the Ethereum social layer.

I've been observing how each project has been interacting with the protocol. I've been a part of exciting discussions where JB was a total enabler of ideas and creativity, and also ones where I've unfortunately had to be the bearer of bad news that the protocol doesn't support the wild thought being proposed. I've seen people spin up projects and raise hundreds of ETH in hours, and seen people give up on the first screen because the "button" they were trying to click wasn't actually a button. After only a few weeks of action I have a sense of what's working, and I've got a laundry list of what could be better.

The goal is to steadily improve things over time. At the base contract layer however, progress must made in big leaps initially with the goal of eventually reaching a steady state as innovation moves to subsequent application layers. JuiceboxV2 is the first big leap. Its goal is simple: to enable more creativity, and remove all points of friction.

JuiceboxV1 was designed with the assumption that communities and project owners have adverse incentives. By using Juicebox, a project owner was committing to particular constraints so that their community could confidently embrace the finances of the game being proposed. Project owners could not mint or burn tokens at will, project owners could not dictate how many tokens were minted per ETH contributed, project owners could not limit who participated in a crowdfund, and project owners did not have a pause button.

Turns out this was a bad assumption to roll with at the base protocol layer. If a community and its owners are one and the same, flexibility is a requirement for total creative expression. It turns out that communities almost always crave a custom treasury strategy that fits their ethos and proposes a game that differentiates them from others.

Projects don't usually have the engineering resources to build, test, and verify such solutions though. This has been a core value Juicebox has provided for people, along with a simple and powerful UI for community members to join in through and follow along with. So far, the frictions that Juicebox removes has justified the treasury strategy constraints that it introduces.

Let's see if we can now do even better.

Proposed changes

Bring your own mint/burn strategy

You'll now be able to bring your own contracts that outline the game you want to propose to your community. You'll be able to plug and play with already-written strategies, or write your own custom one that fulfills your wildest ideas.

Writing a strategy can be simple, or as complex as you want. All that is required is providing a contract that adheres to the IFundingCycleDataSource interface. You'll be able to provide a strategy that decides what happens when someone makes a payment to your project, as well as one for when someone redeems their treasury tokens.

Here's how writing a strategy around a payment works:

You can add a data source contract as a parameter to a funding cycle. Your data source must provide a function that implements the following function specification.

function payData( address _payer, uint256 _amount, uint256 _baseWeight, uint256 _reservedRate, address _beneficiary, string calldata _memo ) external returns ( uint256 weight, string calldata memo, IPayDelegate delegate );

The function receives a handful of parameters from the Juicebox protocol, and is expected to return a handful of parameters back.

Inputs:

  • _payer is the address that issued the ETH payment.
  • _amount is the amount of the ETH payment received.
  • _baseWeight is the weight of the funding cycle during which the payment is being made. This weight is determined by multiplying the previous cycle's weight by the previous cycle's discount rate. Each project's first funding cycle's weight is 10^24.
  • _reservedRate is the reserved rate of the funding cycle during which the payment is being made. This percent is out of 200.
  • _beneficiary is the address that the payer has specified to receive the resulting treasury tokens.
  • _memo is the note that the payer has included in the payment.

Outputs:

  • weight is the weight that the Juicebox protocol should use when minting treasury tokens. The total tokens minted will be amount * weight, where both variables are assumed to have 18 decimal places. Out of these minted tokens, some will be allocated to the _beneficiary, and the rest will be reserved to be distributed to the reserved token recipients according to the _reservedRate.

  • memo is the memo to include with the protocol event that will be emitted as a result of the payment.

  • delegate is the address of a contract that adheres to the IPaymentDelegate interface. If a delegate is provided, it will receive a callback from the Juicebox protocol once it has fully processed the payment. You can return the zero address if you don't need this functionality. The callback your delegate contract should implement is as follows:

    function didPay( address _payer, uint256 _amount, uint256 _weight, uint256 _count, address _beneficiary, string calldata memo ) external;

  • _payer is the same as the one passed in to your data source.

  • _amount is the same as the one passed in to your data source.

  • _weight is the same as the one returned from your data source.

  • _count is the number of tokens that were minted for the _beneficiary.

  • _beneficiary is the same as the one passed in to your data source.

  • _memo is the same as the one returned from your data source.

The recordPayment function where all of these pieces come together can be found here.

A data source and delegate can similarly be provided to your funding cycle that'll shape the recordRedemption function:

function redeemData( address _holder, uint256 _count, uint256 _redemptionRate, uint256 _ballotRedemptionRate, address _beneficiary, string calldata _memo ) external returns ( uint256 amount, string calldata memo, IRedeemDelegate delegate );

Inputs:

  • _holder is the token holder that is redeeming.
  • _count is the number of tokens being redeemed.
  • _redemptionRate is the redemption rate of the funding cycle during which the redemption is being made.
  • _ballotRedemptionRate is the redemption rate that should be used if the project currently has an active funding cycle reconfiguration ballot.
  • _beneficiary is the address that the redeemer has specified to claim the treasury ETH as a result of redeeming tokens.
  • _memo is the note that the redeemer has included in the redemption.

Outputs:

  • amount is the amount of ETH that should be sent from your treasury to the _beneficiary as a result of redeeming/burning _count tokens.

  • memo is the memo to include with the protocol event that will be emitted as a result of the redemption.

  • delegate is the address of a contract that adheres to the IRedemptionDelegate interface. If a delegate is provided, it will receive a callback from the Juicebox protocol once it has fully processed the redemption, but before the amount is dispersed to the _beneficiary. You can return the zero address if you don't want this functionality.  The callback your delegate contract should implement is as follows:

    function didRedeem( address _holder, uint256 _count, uint256 _amount, address _beneficiary, string calldata memo ) external

  • _holder is the same as the one passed in to your data source.

  • _count is the same as the one passed in to your data source.

  • _amount is the same as the one returned from your data source.

  • _beneficiary is the same as the one passed in to your data source.

  • _memo is the same as the one returned from your data source.

The recordRedemption function where all of these pieces come together can be found here.

With these new tools projects can roll out all kinds of treasury strategies, such as:

  • restricting payments to only certain addresses.
  • restricting payments to only addresses that hold certain other assets.
  • offering different levels of  community membership depending on the state of the blockchain.
  • restricting payments to be within min/max payment amounts.
  • creating time weighted rewards.
  • restricting the max supply of community tokens.
  • customizing the amount of treasury tokens distributed per ETH received.
  • minting NFTs for new members.

...or any combination of any of these, alongside any other rule you can express contractually.

Overflow allowance

Previously, a project could only access funds within its specified funding cycle target. All overflowed treasury funds over this target was only accessibly by treasury token holders.

Now, alongside specifying your funding cycle's target, you can specify an amount that you can use from your project's overflow on demand.

This is useful for allocating treasury funds for on-off use cases like bug-bounties, one-time contributions, audits, NFT bids, etc.

Open mint/burn

Previously, you could only mint tokens before receiving your first payment, and burning was only done through the redemption mechanism. All other tickets were distributed purely through the payment process according to funding cycle weights that decreased according to your configured discount rates over time.

You can now mint and allocate new treasury tokens at will. All token holders also now have the option to burn their tokens, for whatever reason.

This gives projects more flexibility to design their tokenomics the way they want, while also having an auto-distribution mechanism through Juicebox's flexible built-in payment mechanism alongside.

Reserved token distribution endpoints

Previously, payout splits could be directed at Ethereum addresses, other Juicebox projects, and arbitrary contracts that inherit from a common interface. Reserved tokens could only go to Ethereum addresses.

Now, reserved token distributions can also be pointed at Ethereum addresses, the owner of other Juicebox projects, and arbitrary contracts that inherit from this common interface.

This is useful to allow for more composable token distributions.

Pay, withdraw, and redeem can all be paused.

Previously, projects had not quick way to pause community interactions with its treasury.

Now, projects are able to individually pause function calls to pay, withdraw funds, and redeem tokens. These controls are configured into each funding cycle.

This gives projects quick levers to use to achieve certain treasury effects.

Adjustable fee

Previously, all projects paid a 5% fee from payouts.

Now, projects will pay at maximum a 5% fee that is adjustable by the JuiceboxDAO. There is also a ceiling fee price that is adjustable by the JuiceboxDAO.

This helps the JuiceboxDAO accommodate more projects and experiments into its ecosystem.

Conclusion

JuiceboxV2 introduces a suite of tools that allow for wild new treasury strategies. What remains constant from V1 is the fact that configurations are locked into funding cycles – if a project runs on 30 day funding cycles, they can specify creative dynamics into the funding cycle, but once the cycle begins changes can't be made until the following one. Also like V1, projects that opt for no duration are choosing the flexibility to make any change on demand.

The implementation of the new contracts is done, we've just now got to document, test, and audit everything. All code is public, as will be all documentation and conversation around this upgrade.

We need eyes and scrutiny. Please don't hesitate to take a look and help pick things apart. If you plan on spending time on this, please reach out to the DAO in our discord and introduce yourself so we can make sure you're rightly compensated for your work.

All projects currently running on Juicebox will be able to seamlessly migrate their treasury to V2.

LFG.

Juicebox DAO 7/17/2021

· One min read
Jango
JuiceboxDAO Contributor

The Juicebox contracts were deployed to Ethereum two days ago. Yesterday, @peripheralist, who built the juicebox.money website, launched a generative art project called Tiles using the Juicebox protocol as its treasury, http://tiles.art. He started a DAO around it, https://discord.gg/bgGwmjWJ85.

With Juicebox, we had built a business-model protocol. With Tiles, he built a beautiful, expressive, and flexible collection of generative art to rally a community around. Neither of us had much of an idea what would or should happen next, but I was excited to take a step back and find out.

My conclusion: From a growth perspective, we can either go out and look for more entrepreneurs and artists that could benefit from using Juicebox, or we can lean into TileDAO since it's the one project that currently uses Juicebox. Since building stuff > shilling stuff is an invariant for me, I think the best thing I can do right now as a $JBX token holder is to participate in TileDAO and help grow it. As other projects start considering building on Juicebox, our job will be to become supporting cast member of their community also.

Juicebox has been deployed

· 5 min read
Jango
JuiceboxDAO Contributor

The first of a series of blog posts explaining the Juicebox protocol, and the game plan for the first several months.


TLDR: The Juicebox protocol's contracts have been deployed to Ethereum's mainnet, and @peripheralist has published a very slick site to interact with them.

Juicebox is a business-model-as-a-service and programmable treasury for community-owned Ethereum projects.

Go check it out at juicebox.money. You can begin using Juicebox as your project's payment terminal with one gas-efficient transaction. A project running on Juicebox.

Motivation

Long story short: indie artists and devs, DAOs, and public goods more generally, need a groovy way to capture the value they create, make reliable cashflow money out of it, and then share it back into the world.

The Juicebox protocol does this by allowing projects to make commitments about how its cashflow will be distributed *before ever receiving payments, signaling to users how their money will be spent ahead of time. *It works really well as a payment terminal and programmable treasury for projects that have mostly predictable costs (like staff payouts, service subscriptions, donations, budgeted initiatives, etc.), and who want to automatically reward their community as they become successful.

How it works

With just one gas-efficient transaction, you can start funding and growing a Juicebox project, and configuring its treasury's payouts.

Once deployed, anyone can fund your project either as a patron by making a payment directly through juicebox.money, or by using other contracts that take fees composably into the Juicebox protocol. Either way, they'll receive your project's community tokens in return. People can pay you directly via an interface like juicebox.money.Or, inherit from JuiceboxProject.sol and use _takeFee to get paid contractually. As the project owner, you can set a funding target that specifies how much it'll cost to create and operate your project for a set amount of time. You do this before anyone sends you money. If your project earns more than its funding target in a set period of time, the overflow can be redeemed by your supporters alongside you in exchange for burning tokens. This effectively pushes everyone's price to pay for your project towards zero as usage grows.

If left unclaimed, overflow serves as a runway for projects.

A project's team and its community are thus incentivized to work together to make sure overflow growth outpaces spending. Funding cycles roll over automatically, allowing people and contracts to affordably fund projects that are important to them on an ongoing basis.

You can configure a discount rate to incentivize earlier adopters, a bonding curve rate to incentive commitment from community members, and a reserved rate to receive some of your own tokens each time someone pays you and receives tokens themselves. Project owners can re-asses their funding needs and cycle configuration over time, and can choose to take their token holders' perspectives into account while publishing these sorts of changes to Juicebox.


There are several ways to configure your Juicebox projects. Here are few cool things you can do:

  1. You can route your income stream through the Juicebox contracts. For example, you can make a version of Uniswap that explicitly only needs $X per month to be sustainably run (labor, ops), where each swap transaction incurs a fee ($Y) that goes towards sustaining the service. If there are enough swaps that month (N) such that N * $Y > $X, then for each subsequent swap, all accounts that have swapped (and therefor paid fees) receive a dividend from the overflowed revenue that is proportional to the amount they've contributed to the project's sustainability thus far. So if N * $Y grows unjustifiably faster than $X — which is the underlying market rent-seeking inefficiency that Juicebox projects try to out-compete — then instead of compounded shareholder wealth aggregation, everyone's price tends towards zero. Meaning people get a nearly-free, community-driven product with no ads, guaranteed data integrity, full business operation accountability, and an open source code base that runs reliably. All built by motivated punks that are getting paid what they ask for and are rewarded alongside the community as overflow grows.
  2. It's easy to program financial dependencies, so your Juicebox project's funding target can be contractually hooked up to those of people and projects it depends on.
  3. You can run a recurring/one-time fundraising campaign and return extra funds to your community, or to other causes.
  4. As the project owner, you can earn some of your own tokens with every payment you receives. You'll "unlock" these tokens at the rate with which your overflow grows, not according to some arbitrary multi-year vesting schedule. These reserved tokens can then be contractually distributed to staff, or to other causes.

There's nothing more exciting than working on/with/for the Ethereum ecosystem these days – new artful minds are being welcomed into cryptowallet-life everyday, and brilliant experiments are being crafted on the regular. It's a creator's dream – there's no need to manage infrastructure,  growth is driven by your community, and financial expectations can be anchored down by code. The Juicebox protocol was created as a means to further this end.

If you have questions or want to contribute, don't hesitate to hop into the Discord.