Joystream / joystream

Joystream Monorepo
http://www.joystream.org
GNU General Public License v3.0
1.42k stars 115 forks source link

Content directory imposed CRT constraints #4151

Open bedeho opened 2 years ago

bedeho commented 2 years ago

Background

One of the main issues with CRTs on DeSo was lack of long term alignment between issuer and buyers. Unfortunately for them, they did not have vesting, which we do, but we can do even better: governance.

Proposal

Allow lead, or council, to set global constraints on CRTs that can be issued, e.g.

This is not a spec, it's an idea, implementer should come up with concrete design before starting.

Probably also constraints on sale terms and other parameters is also sensible. Implementer should provide exhaustive list of constraints.

┆Issue is synchronized with this Asana task by Unito

ignazio-bovo commented 1 year ago
Parameter Name Governance Constraint required Comments
Revenue split - timeline duration
Revenue split - max split value
Vesting schedule - cliff amount percentage max value
Vesting schedule - max duration
Vesting schedule - max blocks before cliff
Token sale - max CRT amount that can be issued in a sale
Token sale - max sale duration
Token sale - cap per member
Bonding curve - max value for $a, b$ params 100% value for both $a,b$ is maximum
Bonding curve - max reward account Setting 100% value allows the CC to block issuance via amm
Content directory - max amount of daily CRT issued Consistent with NFT, avoid proliferation of low quality tokens
Content directory - only verified channels can issue token I have listed several reasons below
Bonding curve - overall constraints to prevent Rugs See below

Why we should allow CRT token only by verified users

What to do to minimize rug pulls

How can a user make a rug pull in our AMM scenario? $\implies$ gain control (own) of a significant amount of the supply and then sell the amount immediately.

bedeho commented 1 year ago

Thank you for this

ignazio-bovo commented 1 year ago
Parameter Name Allow setting min value Allow setting max value Functionality
timeline duration Y Y Revenue split
split percentage Y N Revenue split
patronage rate N Y Patronage
cliff amount percentage value Y N Sale - vesting schedule
vesting durations number Y Y Sale - vesting schedule
blocks before cliff Y Y Sale - vesting schedule
CRT amount that can be issued in a sale Y N Sale
Sale price N Y Sale
sale duration Y Y Sale
number of updates for a sale N Y Sale
cap per member N Y Sale
no. of multitransfer destinations Y (=1) Y Transfer
value for the pricing slope param a Y Y AMM
value for the pricing intercept param b N Y AMM
bond transaction fee governance param governance param AMM
unbond transaction fee governance param governance param AMM
amount of creator token issued in a (day, weekly, monthly) N Y Issue Token
Only verified channels can issue token governance param governance param Issue Token

governance param, means that only governance is allowed to set value for the param (via proposal), hence there's no need to bound user input range by min,max.

Consideration on AMM parameters

Risks related to starting AMM after a sale

Suppose the AMM is started after a sale:

A naive CC can set the price to be p_init_amm > p_sale. Thus for example one that has bought CRTs during the sale can possibly unbond them later for a free profit.

:point_right: Question

Chosing types

In the implementation I think that

https://www.desmos.com/calculator/hqm4li5mkc see possible values for a,b (after looking around in various projects it appears to me that we should just simply focus on the CRT/JOY unit price as the supply changes)

:point_right: Questions

I think also actions could be permissioned, so like launcihng an AMM , or a public sale, etc. I am not sure how important this is at this stage, perhaps we skip that?

There are channel action permission for every CC extrinsic (related to the crt):

We have no notion of on-chain verification of channels, which this proposal would require. We had a metaprotocol version of this here Verified status for channels #2586, but can you make a new runtime level spec which describes how to do it and what migration would be done. In particular, who can verify? can you un-verify, etc

A proposal mechanism can be added for channel verification

Goals

ignazio-bovo commented 1 year ago

Open questions for AMM implementation

Fees

We are charging 1% tx fees on buy order (when CRT is minted) and 10%on sell order (when CRT is sold). These values are can be set by the governance. :point_right: Where are we directing the proceedings from TX fees? Council, Content creator, etc..

Parameters a and b

We could go on and discuss how much max and min market cap and supply a CRT could possibly have. But I think is best to settle on the fact that a,b will be u128 integers and their range can be set by the governance. :point_right: do you agree @bedeho ?

AMM deactivation

Leszek raised the question about whether the CC can deactivate the AMM as he pleases. So far in our design is not possible as we require the AMM JOY reserve amount to be depleted before closing. :point_right: : Can the CC close the AMM at his discression, maybe after announcing a heads up period?

bedeho commented 1 year ago

Where are we directing the proceedings from TX fees? Council, Content creator, etc..

Burned. Also, make sure the fee logic works similar to NFT related fees, in terms of what takes precendent between creator and platform fee, etc.

But I think is best to settle on the fact that a,b will be u128 integers and their range can be set by the governance.

Sounds good.

Can the CC close the AMM at his discression, maybe after announcing a heads up period?

I don't think that makes sense, where does the $JOY go and also less clear that this can't lead to problems?. Lets at least start with the more narrow case that $JOY == 0 first, then if people really want to deactive AMMs all the time in other cases, this can be reevaluated.

ignazio-bovo commented 1 year ago

One last question: After some discussion (before implementing AMM) we decide to settle that the computation for eval

price(x) = a * x  + b, x = CRT supply

what it turns out is that if we instead set x to be the amount minted through the AMM then accounting for a,b becomes much simpler. For example if AMM is activated after an initial sale we can enforce b = sale_price, furthermore the AMM price is no longer affected by external issuance events (like patronage) avoiding thus potential price variation not related to AMM activity specifically

ref: https://github.com/Joystream/joystream/pull/4434#discussion_r1032525864

bedeho commented 1 year ago

I don't exactly understand what problem you are trying to solve here, perhaps we should have a quick chat, but AMM launching client can set a & b however it likes at that time, this is what we decided right, so this means the client can set a & b which is sensitive to past sales or whatever. Having runtime enforced constraints seems too risky at this stage.

Lezek123 commented 1 year ago

Having runtime enforced constraints seems too risky at this stage.

If x = amm_supply, then I think there needs to be such constraint, otherwise the creator can just set b = 0, a = some_very_small_number buy lots of their own token and dilute everyone who participated in the sale, making their tokens worthless.

If x = total_supply we don't need to enforce specific b if we enforce contraints on both a and b instead (a * current_supply + b = last_sale_price), but then we're limiting the slope of the price function by a lot, essentially allowing only very flat ones (assuming there was already a sale) OR we have to allow negative b, which has its own set of issues/complications. There are also issues with patronage / non-amm burning affecting the price as described in https://github.com/Joystream/joystream/pull/4434#discussion_r1032525864, which makes the AMM in general very unintuitive and requiring a lot of client-side explaination (for example, the AMM started at price $100, why can I no longer sell below $110 if someone claimed patronage in the meantime etc.)

bedeho commented 1 year ago

creator can just set b = 0, a = some_very_small_number buy lots of their own token and dilute everyone who participated in the sale, making their tokens worthless.

I don't know how serious this specific problem is, or if we should do anything about it now, as the attacker model here is quite malicous, so it is really reserved for more or less fake accounts, or for a $CRT market where people put money into totally unknown, but real, accounts, and then those real accounts don't mind scamming these third parties. I'm not sure how much to prioritize that right now. I find this particularly difficult as I lack any really clear mental model of exactly how these bonding curve AMMs really work, despite my best attempts to try to find something formal on this.

Seems to me we have these options

  1. do nothing: allow any values on runtime
  2. require AMM to have initial price (b) to be no less than last public sale: this does not prevent same attack, but where sales are done in some OTC/CEX/third party DEX environment
  3. have runtime level values, set by content lead or council, which are enforced uniformly across all channels
  4. require curator approval of launching an AMM, either if there has ever been a sale, or perhaps unconditionally at all times. This sort of constraint could be turned on or off globally, just to avoid it overburdening everyone if it is not a big deal over certain periods of time. This solution also has benefit that it can allow more nuanced oversight which can help with lots of different scenarios that can occur

Personally I think we should just stick with 1 for now, because its an error case which will be rare, and seeing problems before adding a fix is better. It may just be that the whole bonding curve AMM model needs to go, and we really need to add full uniwap (v2) style liquidity pools, or even order books, who knows. I am just not very confident making an armchair decision at this point.

ignazio-bovo commented 1 year ago

Constraints reviewed

Parameter Name Allow setting min value Allow setting max value Functionality
timeline duration Yes, identified during product meeting Not necessary Revenue split
number of blocks between split announcement and start Yes, identified during product meeting Not necessary Revenue split
how much of a channel revenue should be devoted to a revenue split No, not necessary we just check the amount to be > 0% (as 0% has the same meaning as no split since no profits are distributed) No, not necessary Revenue split
patronage rate No, to allow 0% inflation Yes to avoid dilution by issuer / overinflation Patronage
cliff amount percentage value No, I think 0% cliff is acceptable No Sale - vesting schedule
vesting duration No, (see considerations below) No, (see considerations below) Sale - vesting schedule
blocks before cliff No, so vesting can start immediately No, even 100 years period is allowed Sale - vesting schedule
CRT amount that can be issued in a sale No -> can you sell just 1 CRT? -> Yes No Sale
Sale price No, as token in a sale are not minted directly and there's no risk of issuer diluting the supply with a low sale price No, this could be way for issuer to inject JOY into the project (via a sybil account) Sale
sale duration Yes, already there Not necessary Sale
time between sale issuing and start No, (see sale part in considerations) Not necessary Sale
number of updates for a sale No (not a serious problem IMHO) No (not a serious problem IMHO) Sale
cap per member No, just a check that cap > 0 should be ok No max cap (as it is project dependent) Sale
value for the pricing slope param a Yes, (see Amm considerations) Not necessary, the only problem that could arise is numeric overflow (but we do use saturating / checking arithmetic to prevent that) AMM
value for the pricing intercept param b No (See AMM considerations) No AMM
amount of creator token issued in a (day, weekly, monthly) (Not enforceable directly) No if we allow verified channels only, otherwise yes as it is consistent with NFT limiting policy Issue Token

Considerations

Attacker model

The attacker model in which a issuer would dilute the supply and/or undercut a previous sale/amm with a subsequent sale/amm is quite malicious and def. not typical of a long term oriented project. With that said I have nonetheless set constraints for the min. value of the slope parameters and max patronage rate. These constraint can be effectively disabled by the council by setting eg max patranage rate = 100% and min slope parameter = 0.

Patronage rate

If set too high it could dilute the supply and cause overinflation. In the implementation it is a percentage so it has at value in [0,1] range. It can only be decreased by the issuer.

AMM parameters

Hence, no constraints will be set on b.

Vesting Schedules and other parameters

Ref

https://github.com/paritytech/substrate/blob/master/frame/vesting/src/vesting_info.rs