Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creator Tokens Requirements #2362

Closed
bedeho opened this issue Apr 26, 2021 · 36 comments
Closed

Creator Tokens Requirements #2362

bedeho opened this issue Apr 26, 2021 · 36 comments
Assignees
Labels
audit-3 content-pallet idea An idea for a new feature in any part of the Joystream runtime

Comments

@bedeho
Copy link
Member

bedeho commented Apr 26, 2021

Background

Already assumes this has been done

#3263

in particular the built in channel accounts for holding $JOY earned.

Requirements

A given generic creator token is herein referred to as $CRT. Here is a super simple state machine diagram which captures the major states and transitions.

creator!UNITO-UNDERSCORE!tokens

Issue $CRT

A channel owner, but not collaborator, can issue a fungible token controlled using normal Substrate accounts, if one does not already exist, with parameters:

  • Ticker: Short identifying string which is unique across all other creator tokens in the system.
  • Creator Allocation: An account where a given number of units of the initial supply, denoted I below, with optional cliff+linear vesting schedule.
  • Revenue Split %: what %, S of channel revenue the token holders are entitled to.
  • Description: a plain text description.
  • Initial Offer: There are three possible initial offer states, and issuance allows for specifying initial parameters for these
    • sale: a token sale, possibly followed by the AMM state, see for more information below
    • AMM: an automated market maker.
    • idle: an idle state, from which a sale can be initiated later.
  • Patronage Rate: % used for calculating patronage to channel owner.
  • Transferability Policy: Policy (see below).
  • Metadata: can be used by apps to add richer semantics.

Let the actual dynamic supply of the token at any time be denoted by Q.

A note on decimals

One unit of the ticker symbol of a token refers to 10^18 base units of the actual token. This is purely a UI concept, and it means all input and output fields of UIs should use this denomination, hence there can be up to 18 decimal places. So if the user inputs 1,87 this means 18700000000 units as understood by the runtime, or if the runtime has unit balance 3427812313251 then UIs should display 0.00000342781.

General

  • The token must be compatible with Polkadot ecosystem fungible token standard, and work with major Polkadot ecosystem wallets (Polkadotjs, Talisman, etc.). The most prominent standard I have found is orml_tokens::MultiTokenCurrencyExtended, from ORML. It is for example used by AMMs like
  • Note that $CRT ownership is through raw accounts, not as members. This does not prevent members from showing they own $CRT, because if the account is a member staking account that is bound, then exactly one member can prove ownership. Ironically, this is not the case for controller accounts, as it is in principle possible for two distinct members to have the same controller account. This convention about how to bind $CRT ownership to members is something apps can take advantage of and encourage.
  • Remarks extrinsics for owner, collaborators and $CRT holders.
  • A token with a live token issued cannot get deleted, updated this permission issue => On-chain content dispute and resolution #2760

Patronage

  • The patronage rate is a non-negative floating number, which if provided during issuance, refers to the annual % inflation which goes to the owner. Notice we here mean owner, as owner, not the member, so if the channel was to be transferred to another owner (planned Channel ownership transfer (or swap with payment) #2816), it would flow to the new owner.
  • The payout occurs through the owner initiating a cashout, flowing to their member account, which results in a suitable number of $CRT tokens being minted in this account. This calculation is straight forward, as it only needs to know when the last cashout, or change in issuance, occurs. Critically, if there is a change in issuance for any other reason as part of the system features (e.g. burning, or anything else), then there should should be a tally kept in the channel which reflects what would have been paid out to the owner if they had cashed out now, and then the timestamp for the cashout action is reset. This allows
  • The rate can only be reduced, by the channel owner (not collaborators), or entirely removed. It cannot be increased.

Transfers

  • There are two transferrability policies: permissionless or permissioned. The former implies all $CRT transfers are allowed. The latter implies that only transfers to whitelisted destination accounts is allowed. When permissioned, there can also be an initial whitelist commitment provided, which is a merkle root over the set of accounts which can get whitelisted. There is no upper bound to the number of whitelisted accounts at any given time.
  • An account can get whitelisted by providing (in join_whitelist) a Merkle proof of inclusion in the whitelist commitment.
  • Channel owner, but not collaborators, can under a permissionless transferability policy add additional accounts that are whitelisted.
  • Channel owner, but not collaborators, can under a permissionless transferability policy update the whitelist commitment.
  • $CRT holder can do a multi-transfer where a small finite list of accounts can credited, and the transfer only succeeds if all accounts are compatible with a possible permissioned policy.
  • $CRT can be burned which results in the balanced being reduced from the account and the issuance of the token being reduced.
  • A $CRT account should get removed from storage if balance drops below some existential deposit limit, e.g. post burn or transfer. Remember to also remove from the whitelist if present.
  • If all accounts get removed, the token gets de-issued. This can only occur during a burn, as a transfer will at least leave destination account with non-negative balance.

Revenue Split

The key objective here is how to reward value, pro-rata, only once, to each $CRT holder, this is why the staking is required.

  • Unless the revenue split % == 0, it is no longer possible to do a normal withdrawal from the channel account, instead one can initiate what is called a revenue split. Only the owner can initiate a split, not collaborators. When a revenue split is initiated, it is for a certain amount X (user input) of $JOY, no more than the current balance of the channel, Y. The owner specifies some account during split initiation, where the owner share of X is diverted, that is X*(1 - S/100). If the owner also holds actual $CRT, the owner can also receive value via this mechanism by doing the same as normal token holders, as will be described next. Notice that if there is any additional channel revenue after the split is initiated and is ongoing, that is not included in the split, as we are committing to X. Also remember that it must be checked whether channel is currently specifically, or generally, blocked from doing cashouts/splits (see Finalize channel payouts in runtime #3263).
  • The revenue split last a certain predefined number of blocks, called the revenue splitting period. This period length is a parameter value which the lead (for now, perhaps council in the future). During this period, any token holder (not member, token holder!) can claim part of the revenue split by staking the $CRT balance in an account. A token holder staking V number of tokens in such an account will, upon staking, receive (V/Q)*X*(S/100) in $JOY from the channel balance to any account of their liking. Importantly, while staked, $CRT cannot be transferred to any other account. Tokens staked for one revenue split are not counted as staked for any subsequent split automatically, this will require restaking them specifically for that split, and it is only then a part of the revenue for that split is paid out.

Sale

A sale is an event which is meant to provide some liquidity for the channel owner.

  • A sale can be initiated during issuance or from the idle state, but only by channel owner, not collaborators.
  • It is defined by initial settings around
    • unit price in $JOY
    • upper bound on quantity of $CRT on sale
    • block in the future where sale starts, or alternatively just starting on block where
    • number of blocks the sale lasts
    • optional sale whitelist Merkle committment, payload stored in channel storage if provided. If the transfer policy is permissioned, then all buyers present in this whitelist are automatically included in the transfer whitelist. Additionally, it is possible to associated an optional quantity cap per buyer if there is a whitelist. Different buyers can have different caps, and some can have no cap.
    • optional cliff+linear vesting schedule.
    • raw metadata
  • It is possible to update the start+duration of a sale which has not yet started.
  • During the sale, all funds raised go into the controller account of the owner. Hence if ownership is transferred during the sale, new owner receives proceeds.
  • Anyone eligible to purchase can purchase up to max(funds left, their whitelist cap), and purchase is immediately executed. $CRT is minted on each sale.
  • There is a $JOY % burn fee, set as a parameter by the council, which is charged on top of each purchase.

Automated Market Making

This feature requires a short prelude. The idea here is that these assets are extremely long tail bespoke assets, with very low liquidity. It would be very useful for all parties if there was some minimal level of market making which supported people obtaining, or reducing, exposure to such assets. Relying on active traders to manage orderbooks on another DEX/CEX is very possibly not a great solution. Instead, the idea is to have a very minimal automated market maker for each $CRT token in our chain. With that said, I am not entirely happy with this feature. The whole idea of bonding curves for this is something I see used for similar use cases, but the fully implications of it are not apparent to me. I did also consider us going with a more sophisticate product rule (x*y=k, ala Uniswap) system, which seems more well tested and economically rational to me, however it is also more complex, and requires liquidity providers.

  • An AMM can be launched either during issuance or from the idle stage, but only by the channel owner, not collaborators. It is launched with user defined inputs
    • minimum $JOY price: starting price at q=0
    • an upper bound on how much $CRT the curve can sell/bond.
  • A (suitable) bonding curve is used to serve as an automated buyer & seller of last resort <-- must be selected!
  • There is a $JOY % burn fee, set as a parameter by the council, which is charged on top of each $CRT purchase.
  • A buyer can provide $JOY in exchange for $CRT, and if permissioned transfers are enabled, the buyer account must be whitelisted. The $CRT is credited to the buying account.
  • A seller can provide $CRT in exchange for $JOY, and if permissioned transfers are enabled, the seller account must be whitelisted. The $JOY is credited to the seller account.
  • A buyer and seller must be able to specify some tolerance of how much the price may have moved against them before the purchase should not get executed.
  • Notice that one cannot exit the AMM stage if one enters it.

Resources

https://github.com/AragonBlack/fundraising/blob/master/docs/components/bonding-curve.md
https://yos.io/2018/11/10/bonding-curves/
https://medium.com/coinmonks/token-bonding-curves-explained-7a9332198e0e
https://www.linumlabs.com/articles/bonding-curves-the-what-why-and-shapes-behind-it
https://github.com/realnimish/polkadot-amm/blob/main/tutorial.md
https://www.linumlabs.com/articles/bonding-curves-the-what-why-and-shapes-behind-it

Technical Constraints

  • There can be an unlimited number of channels with tokens.
  • A channel can only have one token issued.
  • There can be an unlimited number of token holders of each token.

Note

This is one way in which the implementation can be done.

  1. Issuance
  2. Transfers
  3. Patronage
  4. Revenue Splits
  5. Sale
  6. AMMing

It seems like most of this should be in its own fresh pallet, which uses an authentication trait to verify actors int he content directory, and also which exposes some simple method calls that allow the content directory to read certain things, like whether a given channel has a token issued or not. There is some need for cross pallet mutation, like potentially trying to mutate channel balance in revenue splits, but perhaps it can be minimal. It would be preferable if the existing content directory could remain ignorant about almost everything relating to creator tokens, and only have the dependency go in one direction: creator tokens -> content directory. One way to do this is to have certain key

Anyway, this will get more clear once work begins, it's just a starting place.

  • These requirements are not set in stone, in particular we have to be sensitive to tradeoffs imposed by having to comply by yet-to-be determined interoperable asset standards, and certainly the AMM side of things needs further scrutiny to make sure it is likely to support the intended goals of the creator and the corresponding community throughout the life-cycle of the endeavour.
  • Remember state bloat management! I think whitelists state is probably the only thing needed.

┆Issue is synchronized with this Asana task by Unito

@bedeho
Copy link
Member Author

bedeho commented Apr 27, 2021

Should interoperate with #2365.

@bedeho
Copy link
Member Author

bedeho commented May 27, 2021

Addendum:

For simplicity:

  • lets only allow initial minting, not perpetual.
  • lets allow that if the channel owner holds all tokens, they can "remove" or kill the social token for the channel.

@bedeho bedeho added runtime idea An idea for a new feature in any part of the Joystream labels Dec 9, 2021
@bedeho bedeho changed the title Design: Creator Tokens Idea: Creator Tokens Dec 13, 2021
@bedeho bedeho changed the title Idea: Creator Tokens Creator Tokens Dec 13, 2021
@bedeho bedeho changed the title Creator Tokens Creator Tokens Requirements Dec 15, 2021
@bedeho bedeho mentioned this issue Dec 15, 2021
@bedeho bedeho added the audit-3 label Feb 23, 2022
@bedeho bedeho added the mainnet label Feb 23, 2022
@mrexpat
Copy link

mrexpat commented Mar 4, 2022

Is both a fixed and non-fixed issuance possible? Might have missed it but I'd imagine the option should be there?

@mrexpat
Copy link

mrexpat commented Mar 4, 2022

A common problem that occurred A LOT on Bitclout were pump and dumps. The actual owners of the tokens/accounts didn't even need to be in on it, any group of scammers could choose a creator token to pump and dump. Because most creator tokens had such small transaction amount and volume it meant any group of scammers could have a large impact on the price of a token.

Often times what they would do is create fake profiles of people with existing audiences on other social media platforms and use the narrative that "so and so just joined bitclout, now they'll go bring their existing audience over.. get in early". It worked and I witnessed a lot of ppl getting rugged. The way they successfully did this was based on the fact that most profiles on bitclout would use the same handle as they had on Twitter. If the influencer/famous person in question already had a reserved handle on Bitclout the scammers would use some other social media handle instead, such as their instagram handle, to seem legitimate, and because these pump and dumps occur so rapidly people throw caution to the wind and invest quickly before others find out that "Ronaldo just set up his bitclout account, he will share it on his instagram stories soon".

One partial remedy to this was what they called "Founder Reward Percentage" (FRP) which was set by the owner of the channel. If the FRP was 10% and an investor bought $100 worth of the creator token, the owner of the account would receive $10 of that, and the investor would get $90 worth of the creator token. This of course was transparent and the investor would be aware before approving the transaction.

This FRP was originally paid out to the account owner in the creator token currency, but upon community feedback they changed it to be paid out in the Bitclout currency instead, which was a good idea as this allowed the creator to actually spend the money without seeming like they weren't bullish on their channel by withdrawing their own tokens.

Now, how does this prevent pump and dumps? Well if there is a cost to buy into a token you'll only really do so if you plan to see it through for a longer period of time. If it's free to buy creator tokens then pump and dumps will be rampant, as they have no "cost" to recoup and can just buy in and out of creators without thought.

I'm not sure if this is natively prevented by some other mechanism in our scheme, but thought I'd share it here for your review @bedeho .

To add to this: Bitclout had no fees on the transactions.. which I do believe we'll have, so that would be a partial deterrent for sure.

@bedeho
Copy link
Member Author

bedeho commented Mar 4, 2022

Now, how does this prevent pump and dumps? Well if there is a cost to buy into a token you'll only really do so if you plan to see it through for a longer period of time. If it's free to buy creator tokens then pump and dumps will be rampant, as they have no "cost" to recoup and can just buy in and out of creators without thought.

This sounds like a very expensive and roundabout way to prevent manipulation. We actually do have fees planned, but not for the creator, but for the platform, but it would have the same effect. But as a remedy it seems both expensive and ineffective. You are saying it ended up working? If the amount of abuse declined, could that be for other reasons?

Seems the core problem is fake profiles: since Joystream has on-chain governance, we can try to address that more directly, as curators can get involved, but this would require more thought, and perhaps more importantly, more data and examples of how exactly people are abusing the system.

Bitclout had no fees on the transactions.. which I do believe we'll have, so that would be a partial deterrent for sure.

It has fees, or, we can just crash the bitclout chain right now. Perhaps they paid fees on your behalf, I don't know, but no fees is not really a thing unless you Sybill control who gets onto your system in some other way.

@mrexpat
Copy link

mrexpat commented Mar 4, 2022

First let me clarify: the Founder Reward Percentage was not deployed as a mechanism to fight pump and dumps, that was just one of the side effects it had. Its primary use case for existing was that.. when you really boil it down, having people invest in your coin does not directly yield any rewards to the token owner. A Joystream channel could have a token worth $100m, and by that alone, they would not have any money to actually buy things with.. UNLESS they withdrew some of their own tokens which would have gone up in value.

The problem with that is the fact that it's on the blockchain and therefor any creator cashing out any amount of their tokens sends a signal of "this creator does not believe in himself, look at him cash out his own token".

I can almost guarantee that someone will develop a program that notifies Joystream creator token holders when the owner of the tokens is cashing out their own tokens, because this of course is a sign of rugging, and we know how fickle crypto folks are (rightfully so).

So if I hold $BEDEHO tokens I'll sign up to be notified if Bedeho cashes in $BEDEHO for $JOY because it could potentially be the case that he's rugging the investors and if that's the case I don't want to be the last one holding the bag.

The FRP actually gives the token owner non-creator tokens when someone invests, that they can use without needing to send such bad signals (in Bitclout case those rewards are paid in the Bitclout token which means they can go spend them).

This is actually a separate topic from what I started commenting on, but also one I think is valuable to consider.

This sounds like a very expensive and roundabout way to prevent manipulation. We actually do have fees planned, but not for the creator, but for the platform, but it would have the same effect. But as a remedy it seems both expensive and ineffective. You are saying it ended up working? If the amount of abuse declined, could that be for other reasons?

I'm not sure what is expensive? The fee to the investor? The Founder Reward Percentage is set by the token / account owner. It can also be set to 0%.

It did work to prevent pump and dumps, yes. It was not for other reasons because this was a feature that was made from the start, not something they deployed later on. The way you knew it worked was that there were not many, if any, pump and dumps involving creator tokens that did actually have a FRP set to say 10%.. it only happened when the FRP was set to 0%, or something close to that.

Seems the core problem is fake profiles: since Joystream has on-chain governance, we can try to address that more directly, as curators can get involved, but this would require more thought, and perhaps more importantly, more data and examples of how exactly people are abusing the system.

This is fair, but hard to deal with directly I think, as these profiles would be created, pumped, and dumped, in less than an hour so you'd need incredibly responsive efforts to combat it. With that said the amounts were never huge, a couple of thousand dollars at a time, at most.

To summarize I think the fact that the token owner had the option of adding their own Fees into transactions was a fantastic way for creators to earn actual tokens (that were not their own token) they could spend, without needing to cash out their own tokens which sends really bad signals. What's the point in having people invest in you if there is no actual direct benefit of that? If you can't cash out any amount of your own tokens in order to use the money without sending bad signals, that's an issue for creators.

Again, the rugging prevention was a side effect of this.

@mochet
Copy link

mochet commented Mar 4, 2022

Revenue Split:

  1. This states in the first quoted line only once but near the end it is inferred that future splits can happen. I assume that the revenue splits can be initiated by the Channel Owner multiple times?
  2. Is a Revenue Split mandatory when creating a Channel Token?
  3. I am trying to ensure I am comprehending this aspect of the design fully — is it correct that by making a creator token the channel owner will no longer be able to access normal rewards, and that all future rewards will only be accessible via performing a Revenue Split? And that in such an instance, the Channel Owner is also receiving a proportion of the revenue because of their own Creator Allocation?
  4. Is it also correct that a Channel Owner could decide to target splits that always leave a “healthy” amount of $JOY in their account, and that this mechanism would possibly act to signify exploitive vs sustainable Channel Owners?

Transfers:

  1. Is it correct that the whitelist + permissioned policy not only applies to the initial sale but also to all holders of the token who receive it—they wouldn’t be able to send the $CRT they possess to anyone else besides that whitelist? In effect allowing the Channel Owner to not have their token available freely in the marketplace?

Further Questions:

  1. So creators can issue a creator token with a bunch of options, and to issue this token they’d have to pay a one-time fee in JOY to create the token.
  2. My biggest question is when two users exchange $CRT are they paying transaction fees?
  3. Are the fees in JOY or $CRT? or both?
  4. If they’re compatible with the polkadot ecosystem and various wallets, what happens to transaction fees when they “move” to other platforms?
  5. Can a creator pay the fee required to issue a creator token and instead of an initial offer just manually distribute the token however they want to (such as airdrops, giveaways etc)?
  6. I believe the answer to the above is likely no, in which case, is there any upper limit on how much the Creator Allocation can be?

Final Question:

  1. Can the channel owner actually sell/exchange the tokens within Creator Allocation or are these locked?

It has fees, or, we can just crash the bitclout chain right now. Perhaps they paid fees on your behalf, I don't know, but no fees is not really a thing unless you Sybill control who gets onto your system in some other way.

I did review Bitclout and its an almost completely closed system. “Creator coins” don't actually exist, it is all just their native token tied to accounts somehow and its initial issuance is controlled by the company that runs it and some sort of pricing formula is involved.

I wasn't able to find any exchange that sold any of the "creator coins" and all of them have their value determined solely by the amount of Bitclout’s native token that they hold. So their "creator coins" are very, very highly controlled, with basically only their platform allowing buying and selling--I am pretty sure that this restriction if anything significantly increases the incentives for pump and dump operations.

I think the rich level of options available here would allow content creators to experiment with different things and maybe just like the early altcoin days when people began showing distaste and distrust towards any premines that some of the available parameters will either have positive or negative connotations surrounding them.

@bedeho
Copy link
Member Author

bedeho commented Mar 7, 2022

This states in the first quoted line only once but near the end it is inferred that future splits can happen. I assume that the revenue splits can be initiated by the Channel Owner multiple times?

Splits can happen only once at a time, but an unlimited number over time.

Is a Revenue Split mandatory when creating a Channel Token?

No. You can either chose to give 0 % to $CRT, or, you could just never do splits, but, if you have split % > 0, then this also means you also cannot get funds out for yourself.

I am trying to ensure I am comprehending this aspect of the design fully — is it correct that by making a creator token the channel owner will no longer be able to access normal rewards, and that all future rewards will only be accessible via performing a Revenue Split? And that in such an instance, the Channel Owner is also receiving a proportion of the revenue because of their own Creator Allocation?

Yes.

Is it also correct that a Channel Owner could decide to target splits that always leave a “healthy” amount of $JOY in their account, and that this mechanism would possibly act to signify exploitive vs sustainable Channel Owners?

I did not understand this really, but they are unrestricted in when they want to do splits, and how much to split out.

Is it correct that the whitelist + permissioned policy not only applies to the initial sale but also to all holders of the token who receive it—they wouldn’t be able to send the $CRT they possess to anyone else besides that whitelist? In effect allowing the Channel Owner to not have their token available freely in the marketplace?

Yes.

So creators can issue a creator token with a bunch of options, and to issue this token they’d have to pay a one-time fee in JOY to create the token.

This is only normal tx fee, the only real burning fees are

  • during sale, "paid" (leaving incidence aside) by the purchaser
  • during purchase from AMM

My biggest question is when two users exchange $CRT are they paying transaction fees?

The one who makes the extrinsic pays, but there is no p2p swap feature like you are describing. The AMM is not a p2p swap, its trading with the chain/curve.

Are the fees in JOY or $CRT? or both?

Only $JOY

If they’re compatible with the polkadot ecosystem and various wallets, what happens to transaction fees when they “move” to other platforms?

This is a complex topic, just getting into it myself.

Can a creator pay the fee required to issue a creator token and instead of an initial offer just manually distribute the token however they want to (such as airdrops, giveaways etc)?

There is no such fee, but yes, you can distribute your token however you like, including doing lots of manual transfers.

I believe the answer to the above is likely no, in which case, is there any upper limit on how much the Creator Allocation can be?

The creator allocation is just a number of $CRT units, and initially this is 100% of the supply. Any other tokens are minted in a subsequent sale or AMM or patronage.

Can the channel owner actually sell/exchange the tokens within Creator Allocation or are these locked?

I decided to add optional cliff+linear vesting schedule based on your comment.

@bedeho
Copy link
Member Author

bedeho commented Apr 5, 2022

Why not the channel account internal to the module? Those funds could serve as Cash (in balance sheet term) for future expenses?

That does not make sense, because channel account is a shared resources which $CRT holders have a claim on.

I think we are fine if every sale is backed by JOY it should be fine

what do you mean by this? by backing with JOY? Do you mean no minting/dilution?

, we could eventually prohibit the creator to buy his own token, to avoid dilution

You can't block this... Sybil identities.

@ignazio-bovo
Copy link
Collaborator

That does not make sense, because channel account is a shared resources which $CRT holders have a claim on.

Then you mean a $CRT instead of $JOY in the original question?

what do you mean by this? by backing with JOY? Do you mean no minting/dilution?

$CRT amount X is minted into member that purchases X during a sale <--> X * sale.unit_price_in_joy $JOY is sell from that member to the sale issuer ($CRT owner)

@Lezek123 Lezek123 mentioned this issue Apr 7, 2022
6 tasks
@Lezek123
Copy link
Contributor

Lezek123 commented Apr 8, 2022

As is, sale is financed by minting, hence it dilutes all holders, and we don't really have any constraints how this occurs, which means the issuer can just instantly dilute everyone with a sale they buy up themselves for example. What sort of constraints should we be adding here, if any? One way to sidestep all of this is to require that sales are financed from pre-existing $CRT that owner provides, e.g. assigned during issuance or patronage, but this then prevents any larger public fundraising event being an ongoing activity in the future.

I imagine there beeing a cap on total issuance provided during issue_token (let's call it issuance_cap). Multiple sales can be initiated after the token is issued, but there is a guarantee that the total number of tokens sold (or issued in any other way, including patronage etc.) will never exceed the issuance_cap, which means any investor can factor in the highest possible diluance that may happen at some point in the future. issuance_cap could be also a "moving cap", so for example, a token could be issued with an issuance cap of 1_000_000_000, but with each passing block the cap could be increased by, let's say, 1000, making the cap 2_000_000_000 after 1_000_000 blocks since issuance. I imagine the issuance_cap can also be decreased by the token creator, but never increased.

@Lezek123
Copy link
Contributor

Lezek123 commented Apr 8, 2022

To be more percise:

struct MovingCap<Balance> {
  initial_cap: Balance,
  increase_per_block: Balance,
}

enum TotalIssuanceCap<Balance, MovingCap> {
  Static(Balance),
  Moving(MovingCap),
}

struct TokenIssuanceParams<..., TotalIssuanceCap> {
  // ...
  issuance_cap: TotalIssuanceCap
}

@bedeho
Copy link
Member Author

bedeho commented Apr 9, 2022

I like the following about this idea

  1. Its damn simple: simple to reason about, simple to implement, simple to explain. I think it can be made slightly more powerful by allowing issuer to also reduce cap also later, if they find they don't really need it.
  2. It allows the creator to reserve some sort of future funding flexibility.
  3. It provides some guarantee to stakeholders about how much dilution there could be.

I am not quite sure what the implications are for the AMM & patronage side that they are also constrained by this limit. I get that the limit has to be universal, but then this has some cost in these other domains, as those functions stop working, and this now has to be explained properly, and picking numbers during issuance has to be with more care.

There is a separate problem relating to sales which also concerns me: self-dealing. Someone could launch a sale, perhaps at a low price, and snipe most of the allocation themselves through a dummy account. Now you can try to fix this, by adding a minimum lead time before sale begins for example, and there is also the issue that a sale with a suspiciously low price which is all bought fast can undermine credibility of entire project anyway, which then backfires, but it does get tricky. You could imagine getting curators involved, where they have to approve all sales or all sales after the first sale, but this again gets complicated.

What if we do something just ded simple: sales are funded by creators assets, end of story. This solves everything, and the main cost is you can't do dilutive funding. In a way this more closely reflects the nature of the transaction, because the $JOY raised is not a shared asset of $CRT holders, like a normal equity raise for a company, its the personal asset of the issuer. This is because there is no $JOY treasury or governance process over that treasury which $CRT holders influence. I think that would be a useful thing to have, but its too complex for us right now. The issuer can still do multiple sales, for example by selling smaller chunks, or by selling patronage $JOY, so that option is still there. Later we could layer in a proper governance & dilutive funding like $JOY has, if that is something people end up asking for.

WDYT?

@Lezek123
Copy link
Contributor

Lezek123 commented Apr 11, 2022

WDYT?

Sounds good, as this is definitely simpler to implement and reason about and I think it's a good enough starting point.

@ignazio-bovo
Copy link
Collaborator

ignazio-bovo commented Apr 11, 2022

I am not sure about limiting the total issuance. Most AMM bonding curve assume the opposite. I need to investigate...

Update:
Indeed Bonding curves specify price = f(supply) hence if want to cap the supply we would implicitly cap also the max price allowed for $CRT

References:

@bedeho
Copy link
Member Author

bedeho commented Apr 11, 2022

we would implicitly cap also the max price allowed for $CRT

Indeed.

@ignazio-bovo
Copy link
Collaborator

ignazio-bovo commented Apr 11, 2022

How about a cap on the total sale $CRT allocation, instead? like the following:

  • max total sale allocation allowed <= max_percentage * supply at the time sale is issued

@bedeho
Copy link
Member Author

bedeho commented Apr 11, 2022

Yeah, you could still do one 1000 times per day, and again, the self-dealing is still an issue. I don't see any good way of dealing with that some governance around the $CRT, either by stakeholders or curators, and that starts to get really too complicated too quickly.

Honestly: I just don't know. The ability to do dilute financing in the future may even make the issuer an even more committed steward than otherwise, because they have the right to print in the future, which itself is a valuable asset. So it does discourage some level of self-dealing even.

@bedeho
Copy link
Member Author

bedeho commented Apr 11, 2022

How about this: max x % sale dilution per year, in total, and x is a parameter controlled by governance (council or curators).

Still pretty simple, allows some self-dealing, but also dilute financing for honest actors.

@ignazio-bovo
Copy link
Collaborator

ignazio-bovo commented Apr 11, 2022

I have another, more math-like idea, I am putting it out there in case it might be a good one.

  • MAX_PERCENTAGE_BOUND : max percentage of supply at time the sale is started allowed for a sale allocation
  • n: sales nonce for token
  • supply(t) supply for $CRT at block height t

allocation(n+1) for n+1 sales needs to satisfy

allocation(n+1) <= MAX_PERCENTAGE_BOUND * supply(t) / n^2

This allows to control the total inflation induced by self dealing since

SUM allocation(n) <= MAX_PERCENTAGE_BOUND * supply(t) * pi^2/6

Summation taken for n = 1,2,...INFINITY
This should encourage early sales for raising liquidity, while later sales are constrained

References:

Last edit: Apr.11th at 20:27 CEST

@bedeho
Copy link
Member Author

bedeho commented Apr 12, 2022

I have another, more math-like idea, I am putting it out there in case it might be a good one.

I think the benefit of this, compared to my suggestion just prior, is if the platform itself is perhaps not perfectly credible in constraining annual dilution, the cost side is that its less flexible and more complex to explain to users and implement.

I think on balance the prior one would be better in my judgement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
audit-3 content-pallet idea An idea for a new feature in any part of the Joystream runtime
Projects
None yet
Development

No branches or pull requests

6 participants