Token Factory on Penumbra

Feature Request: Token Factory on Penumbra

At Devcon, one idea I heard from a few people I talked to was that they’d be excited about a token factory component on Penumbra that would allow users to mint tokens from within the shielded pool.

This topic is a launchpad for brainstorming in that direction – if you have ideas about use cases for a TokenFactory, please comment here!

2 Likes

As we discussed at DevCon, mint them using Orchestration on Agoric, and then reach that from a shielded pool with just an IBC transfer

In general, +++ on this, would be a very cool primitive to have on Penumbra! I think much like with something like Secret Network having the possibility of deploying a shielded project token would be a great attractor to new projects to build on Penumbra.

Being able to do emissions / pricing via bonding curve would also be an interesting feature to have, although not sure how ‘baked in’ to a TokenFactory that would have to be.

1 Like

So, the cool thing is that because of the way Penumbra works, I think it’s possible to compose together a token factory and a bonding curve to have a completely fair launch token – with no frontrunning the initial price discovery!

Let’s look at how this could work.

Token Factory

In other parts of Penumbra, we’ve adopted a “stateful NFT” pattern for controlling public state from inside the shielded pool. For example, an auction is controlled by an auction NFT, and the NFT has a sequence number, so that each action on an auction can consume the previous state and produce an NFT with the next sequence number. A similar approach could work for a token factory, by adding the following transaction actions:

ActionBurn

This action specifies a Value and burns it explicitly. Having an explicit burn action means that it’s not necessary to do some hacky mechanism and it’s easy to verify that tokens were in fact burned (e.g., it can emit an event).

Value Balance

The ActionBurn consumes the specified value from the transaction’s value balance and produces nothing.

ActionTokenFactoryCreate

This action would specify a Metadata for the token, a nonce, and an initial supply. The nonce would be a random 32-byte value that defines the token’s denom (e.g., factory/[32 hex bytes]), and the chain would check that it’s unused, similar to the way auctions or LPs work. (The chain cannot assign the value, because it needs to be known on the client side at the point the transaction is created in order to record outputs).

Value Balance

The ActionTokenFactoryCreate would contribute the following to the transaction’s value balance:

  • +SUPPLY of the newly created factory/[ID] token
  • +1 of a “token factory NFT”, factory_mint_0_[ID], which represents minting rights over the newly created token

ActionTokenFactoryMint

This action would mint additional tokens, using the token factory NFT. It would specify an amount of tokens to mint.

Value Balance

The ActionTokenFactoryMint would contribute the following to the transaction’s value balance:

  • +SUPPLY of the factory/[ID] token
  • -1 of the factory_mint_[N]_[ID] NFT with sequence number N
  • +1 of the factory_mint_[N+1]_[ID] NFT with sequence number N+1

Using the Token Factory for Mintable Tokens

This mechanism allows two different use cases: tokens that are issued by a central party who retains minting rights, and tokens that are minted once and then have a fixed supply.

For an application like https://cigzone.org , where minting rights are a feature, the initial token factory creation would look like

  • Spend (to pay fees)
  • ActionTokenFactoryCreate (with initial supply, could be 0)
  • Output (to store newly created supply, if any)
  • Output (to store the mint authority token)
  • Output (to store change from fee payment)

The issuer can then mint new tokens on demand as needed, by using the ActionTokenFactoryMint. Currently, they can’t programmatically encumber minting, but this limitation of the protocol would be difficult to change without becoming Aztec (let’s put that off into the further future).

Using the Token Factory with Bonding Curves

Now let’s look at the case where a user wants to perform a fair launch using a bonding curve. Penumbra is actually incredibly well-suited to this, because all DEX operations are batched, meaning that all users access the bonding curve at the same “time”.

Penumbra LP positions have fixed prices, but they can be used to replicate the behavior of a bonding curve, by creating a sequence of positions with ascending prices. The Penumbra DEX will index these and route through each of them in turn.

A fair launch transaction on Penumbra would look like

  • Spend (to pay fees)
  • ActionTokenFactoryCreate (with fixed initial supply)
  • ActionBurn (to burn the mint NFT)
  • Repeated:
    • PositionOpen (to define one part of the bonding curve, with 0% fee and fixed price)
    • ActionBurn (to burn the LPNFT, making the liquidity immutable)
  • Output (to store change from fee payment)

This is really cool, because now the entire supply of the token has been verifiably committed to the bonding curve, and any user can interact with it on an equal footing (no frontrunning). But we can do even better. Rather than having just one bonding curve, the fair launch transaction can define bonding curves to multiple assets. Because the Penumbra DEX can do multi-hop routing, this allows the assets that were previously used to buy the new token at lower prices to be used to provide liquidity on other routes, rather than just being locked away in an inaccessible part of the bonding curve!

1 Like

Even more directly, there could be an ActionTokenFactoryCreateWithBondingCurve that does the LP creation described above automatically, which would be simpler and more efficient.

This all looks great to me :100:. Only thing I would ask to add is an ActionLock / ActionUnlock so that tokens or LP assets could be time locked to a specified future height instead of burned in some cases.

Also it could be very interesting (but possibly more complicated than you want to entertain) to have the TokenFactoryNFT also able to mint subfactories with limited mint capabilities, such as a fixed total amount of tokens they can mint, or a limit that grows with block height, to allow the possibility of limited token supply growth over time.

1 Like

What kind of locking would you want? Currently the design of Penumbra is somewhat hostile to locking at the protocol level, because all user state is tokenized so that it can be recorded privately. What would the goal / use case be?

2 Likes

The mechanism I’m imagining would burn the input asset, while issuing the user an equivalent lock asset which could be later burned (after the unlock height) to remint the original assets burned.

In your notation:

ActionLock

This action would specify a future unlock Height when the burned input will become unlockable, as well as the Quantity and asset to be locked.

Value Balance

The ActionLock would consume the input Value(Quantity of asset) by burning it, and would produce an associated lock asset.

  • +Quantity newly minted lock_[height]_[asset] tokens
  • -Quantity of [asset]

ActionUnlock

This action would reverse the lock action, by consuming and burning Quantity of lock_[height]_[asset] to reproduce the original Quantity of asset. (After validity checking that [height] is lower than the current block height.)

Value Balance

The ActionUnlock would consume and burn the input lock_[height]_[asset] tokens and recreate the underlying locked assets.

  • -Quantity of lock_[height]_[asset] tokens
  • +Quantity of newly minted [asset] tokens

Usage

This construction would allow locked assets to still be fungible and tradable within the normal systems of Penumbra, in much the same way that bonded or unnbonding stake can be. This would enable token issuers to create token vesting schedules, as well as create guaranteed liquidity for fixed time periods, but which could eventually be adjusted or withdrawn and used for project funding and development once price has moved to ranges where the original liquidity is no longer useful.

Concrete Example

Suppose a token creator wanted to utilize Penumbra for a non-memecoin project launch, and did not want to permanently lock all tokens into a fixed bonding curve.
In particular, suppose:

  • 45% placed into a standard bonding curve, with LP tokens burned to provide guaranteed base liquidity. (Incentive to buy early)
  • 15% placed into a 72 hour Gradual Dutch Auction. (Incentive to delay and buy late. These two combined creates strong incentives for rapid price discovery)
  • 15% held back to be paired with proceeds of GDA in liquidity concentrated around resulting price range. With LP tokens to be locked for a year (or month) at a time, allowing for adjustments to price range upon each unlock, but while still providing user confidence that liquidity will be available for at least until the next unlock period.
  • 25% for development fund. (5% liquid, 5% locked for 1year, 5% for 2 years, etc. These locked tokens could still be transferred and allocated from issuer wallet to individual contributors, traded at discounts, etc.)

The token creator could even release the Full Viewing Key of the issuer wallet to create transparency around future unlocking and liquidity adjustment actions, as well as locked token allocations.

This is just an example, but I think the benefits of allowing this level of flexibility (in the space between burning vs having tokens fully liquid) are numerous.

1 Like

Hmm, I can see the use case, but I’m unsure if it makes a ton of sense to do on Penumbra rather than somewhere else. It feels like the product divide is into two categories:

  1. “Fairlaunch” tokens that are never controlled by anyone, from the start
  2. Tokens that have some kind of controlling issuer (even if that control is attenuated by locking/vesting)

In the case of (2), it feels hard to anticipate in advance what all the possible different use cases will be, and what their requirements are. However, if we accept that there’s a controlling issuer, it seems like that issuer could temporarily take control of the supply and then lock it, rather than that being in a single action. And if we accept that, we could also be OK with the issuer sending those funds over IBC to a chain with programmability, then using whatever vesting contract they want. (The rest of the supply can be shielded in Penumbra).

So, my instinct is to keep scope down and focus on (1) while being open to (2).

2 Likes

The TokenFactory seems useful for projects like ours, and would save us from doing the additional step of minting on another Cosmos chain + bridging to Penumbra. We already launched CigZone Marlboro Lights using TokenFactory on Neutron, but we’d be interested in this feature for future product launches such as CigZone Marlboro Reds, CigZone American Spirit Blues, or the highly requested CigZone Cigar Series.

It seems like minting from minting rights would be transparent in this scheme, which is what we want, but would it be possible to have shielded minting and thus hidden supply? Our users prefer transparent minting and supply so they can audit our inventory, but since there is already a trust-assumption with the issuer, maybe some similar projects would be interested in having that information off-chain (with the possibility of proving info about the supply off-chain to an auditor).

2 Likes