Joystream / atlas

Whitelabel consumer and publisher experience for Joystream
https://www.joystream.org
GNU General Public License v3.0
100 stars 45 forks source link

Channel Payouts Design Brief #1813

Closed bedeho closed 2 years ago

bedeho commented 2 years ago

Background

Warning

This brief attempts to give the whole story, everything is not relevant to everyone who may be involved in building this into Atlas, however, it's all here for the benefit of completeness.

Warning 2

This document was really rushed, please excuse the poor writing and sloppy organisation.

What is all the fuzz about?

The DAO can pay channel owners $JOY through a proposal passed by the council, in order to provide them an incentive to continue to publish on the platform, or to retroactively pay for use of their content. Let us for the purposes of this product design brief leave aside

  1. How it is the council decides what to pay a given channel.
  2. How often channels are paid.
  3. What makes this payment activity economically rational or sustainable for the DAO.
  4. The terms or semantics associated with the payments, e.g. whether it is per use, for the future, for the past, etc.

What makes this activity more complex from a product perspective than what may at first appear to be likely, comes from the computational constraints of actually doing these sorts of massive at scale payments in a blockchain system.

At scale, there will be many tens of millions, eventually hundreds of millions, of channels. All need to be paid at some sufficiently high frequency, say once a week or month. It is simply not feasible for the council proposal to absorb a list of, for example, ten million payment records which include the following for each channel

a) channel identifier b) how much $JOY to pay c) reason for this payment

Simply putting this into the ledger would not be possible, certainly in one transaction, but also iterating over 10M accounts and crediting them would be very expensive and take a long time, likely unrolled over many thousands of blocks.

Who is paid?

Keep in mind that for each channel there is a so called Module account. This is an account which is not directly controlled using keys, like normal accounts. It is ownership over the channel which allows for possibly transferring funds from this built in account to some other "normal" user account, like the controller account of the member who owns the channel for example. When a channel owner is paid for some channel, the funds are not directly sent to the controller account of that owning member/curator, or to the collaborator if a channel collaborator is doing it, it goes to the channel account. A second transaction is needed for the channel owner to transfer funds from this account to any other desired account, such as their controller account. When we implement creator tokens, this second step of extracting tokens from the channel account to the owner will get more involved, as the token holders need to get a cut as well, but for now, we can leave this aside. On the product side, it may certainly be fine to batch these two steps (cashout to channel account + transfer to external account) in one step, as this may often be what the owner wants if there is no creator tokens involved.

The Big Idea

The core idea to sidestepping the limit above is to give up trying to credit everyone at once, and instead require people to actively cash out when they want to actually access their cash. This will not at the same uniform maximum frequency for every person, in particular if there is some cashout cost on which people are willing to economise. Moreover, give them a means to do this by exploiting a small cryptographic trick where the blockchain does not need to absorb a gigantic list of what everyone is owed, but rather a tiny digest, and give anyone who wants to the ability to cash out using a small proof which the blockchain can verify w.r.t. this digest, and thus accurately credit the caller.

This explainer tries to explain the technique behind this trick, but when used in another context

https://www.youtube.com/watch?v=r_vrvoGd3RU

Cashing out

Here we attempt to describe how this works at a high level. It has two stages, a first stage where the council is acting - and setting the rewards, then a second stage where a channel owner is interested in cashing out the reward.

The Council

This means that when the council passes a payout proposition, the following happens:

Its important to realise a few things about doing a cashout:

Channel Operator

In order for a channel owner determine what they are presently able to cash out, they do the following:

To actually get the owed funds (which is not V, but rather V minus the total amounts of funds cashed out prior), the channel owner must use the record information with a special cashout extrinsic in the content directory (claim_channel_reward). If this works, the funds end up in the channel account, not the personal account of the channel owning member/curator. A separate extrinsic will be introduced to allow cashing out from the channel account to any other user controlled account (withdraw_from_channel_balance), moreover, a combined extrinsic for doing both atomically will also be added (claim_and_withdraw). There are two reasons the cashout may still fail

Report Format

It has not been determined what the format should be of the report associated with the record of each channel. The simplest thing I can imagine would simply be to have a sort of dated log, where each entry corresponds to a prior council payout resolution and includes

This would at all times provide a full history of why a given channel was credited the value it was, which is useful for everyone. Either way, there is certainly room for the designers and product people to weigh in on what would be suitable here.

Technical Notes

User Stories

Only including MVP stuff here, so no rankings or other kinds of discovery related to earnings.

Channel Owner

Note: the current balance of a channel account is the sum of all revenue from NFTs or payout claims, minus the value of all prior withdrawals.

Channel Viewer

Someone looking at a channel from the outside

Exactly the same as above, except no notifications and no actions for claiming/withdrawing.

Creator Tokens

When creator tokens are added things will work a bit differently for a channel with a live creator token. The short story is that when you try to withdraw funds to your user accounts, you will trigger a revenue sharing event with all token holders. This is worth keep in mind.

TLDR for Atlas designers

┆Issue is synchronized with this Asana task by Unito

kdembler commented 2 years ago

Okay that was a lot to digest. I have some very initial thoughts/questions:

  1. I don't fully understand how the runtime keeps track of which rewards were claimed already and how much a given channel can still claim. You said To actually get the owed funds (which is not V, but rather V minus the total amounts of funds cashed out prior). Does that mean there is some state kept on how many JOYs a given channel has already claimed in its entire existence? Then you can only claim current_V - total_past_claims?
  2. There are upper and lower bounds for the size of an individual cashout, stored in on-chain storage, and subject to discretion of the council. - do these bounds apply to both claim and withdraw?
  3. As a channel owner I would like to be notified when a payout has been triggered by the council. - do you mean any payout or a payout that mentions my channel?
  4. Since there seems to be quite a lot of data fetching and manipulation (and also possible error cases) required to get info on current payouts for a given channel, I would suggest we're conservative with how eagerly we present that data. Possibly even make checking a "manual" action, i.e. you click a button to get current payouts status, instead of this being visible for every channel by default.
  5. The user stories for channel owner don't include any actions, like actually claiming or withdrawing rewards, was that intentional?
bedeho commented 2 years ago
  1. Correct => Does that mean there is some state kept on how many JOYs a given channel has already claimed in its entire existence.
  2. Claims only.
  3. Probably both? A user may want to know that there was a payout, where they perhaps expected to get something, but they did not? Seems fair.
  4. I get your point. I think for your own channel, it should def. be eager, but less important on other channels. I guess picking whatever the simplest thing to execute on is the best starting point.
  5. Doh.... feel free to edit my issue :/
kdembler commented 2 years ago
  1. Just to make sure - if the council wants to reward a channel with X tokens, it will publish a new payout document where my channel will have value V assigned equal to X + Y, where Y is the sum of rewards I have already claimed in the past. Correct? It seems that the chain would be able to validate how much I can claim, then why do we need 👇?

    There is some special state in each channel which prevents the reuse of the same proof multiple times, basically by ensuring that if the channel has already cashed out after the date at which the proposal passed, then they can't do it again.

  2. Hmm, it seems it may be tricky to know when there is a new payout that includes some new tokens for the user. Will need to wrap my head around this
  3. Yeah, was thinking something similar.
  4. Okay, added few
bedeho commented 2 years ago
  1. V is just equal to the total amount of value the council believes you should have received at that time, the council does not try to keep track of how much you have actually claimed at the time they are making their decision, this would be practically a mess, as people are continuously claiming while the council is trying to deliberate and come up with V values for millions of accounts. If its still not clear, lets jump on a call.
  2. There is a new payout as often as there is a new proposal of a given type which executes, call it UpdateCreatorPayouts.
kdembler commented 2 years ago

Yes, that make sense. The question I still have is this: If the runtime knows both: 1. how much rewards council has assigned to me AND 2. how much I have already claimed, it seems the runtime should be able to do a simple check when I'm claiming to make sure I'm not trying to draw too much. If that's the case, why is 👇 needed?

There is some special state in each channel which prevents the reuse of the same proof multiple times, basically by ensuring that if the channel has already cashed out after the date at which the proposal passed, then they can't do it again.

bedeho commented 2 years ago

how much I have already claimed <- this is basically that "special" state :D

kdembler commented 2 years ago

Ahh okay. That quote gave me an understanding that we somehow store which proofs were already "used". All good now 👍

dmtrjsg commented 2 years ago

Adding my 5p and questions

1️⃣

If a channel owner was promised e.g. 10 in a given proposal, but did not cash it out, then they could be promised any new value in the next one, say 5, and this would be a permanent loss without recourse. 

❓ How can we help channel owner avoid the loss of hard earned Joys? One thing coming to mind is to have some sort of minimal grace period constraint for such proposal types; and once executed notify user about next payout approx ETA (based on starting block of proposal + grace period). ➕ Could we add// As a channel owner I want to be informed ab next payout event, so I can avoid losing (potentially) currently un-claimed funds.

2️⃣

..Attempt to mint $JOY for a channel may fail for no other reason than it being out of funds.  In this case, the channel owner is best served to just wait until the budget is automatically replenished, something that happens automatically at some known block in the future.

❓ Correct to assume this cannot trigger a notification (based on what was discussed for NFTs)? Would it be possible to display the countdown till next content working group payout period?

➕ Could we add // As a Channel Owners I want to be informed about my ability to claim previously owed payout, when content wg budget becomes sufficient to settle it.

3️⃣

the council does not try to keep track of how much you have actually claimed at the time they are making their decision

❓ Could we run into a case where channel payouts were promised, at the time of budget being insufficient, then new payouts announced (without consideration of payouts not been paid out also due to insufficient budget), which would over-write the “promises” and effectively resulting channel owner “skipping” a turn w/o ability to withdraw?

ℹ️ 🚫 Out of scope: ..user stories worth singling out as user stories for later:

bedeho commented 2 years ago

How can we help channel owner avoid the loss of hard earned Joys? One thing coming to mind is to have some sort of minimal grace period constraint for such proposal types; and once executed notify user about next payout approx ETA (based on starting block of proposal + grace period).

I am not so sure that makes sense as a remedy, but I take your point. The council will anyway be able to do things like blocking cashouts, so if they don't want you to ahve your tokens, you wont.

Could we add// As a channel owner I want to be informed ab next payout event, so I can avoid losing (potentially) currently un-claimed funds.

I think this can make sense, so basically the council can soft-commit to when the next update will be, which can be helpful, but this will not be binding.

@kdembler technically this can be implemented as a metadata as part of the proposal to make a payout, so you commit ot the ETA for the next one, but you probably also need a separate proposal just to update/unset this later also. Let me know what you guys want to do here.

Correct to assume this cannot trigger a notification (based on what was discussed for NFTs)? Would it be possible to display the countdown till next content working group payout period?

No, that is not correct, that would work fine.

By the way, the funding for the payouts will not come from the content working group after all, it will come from the council budget directly. But that is not of much significance one way or the other to Atlas.

Could we add // As a Channel Owners I want to be informed about my ability to claim previously owed payout, when content wg budget becomes sufficient to settle it.

Should be fine.

Could we run into a case where channel payouts were promised, at the time of budget being insufficient, then new payouts announced (without consideration of payouts not been paid out also due to insufficient budget), which would over-write the “promises” and effectively resulting channel owner “skipping” a turn w/o ability to withdraw?

Did not understand this.

toiletgranny commented 2 years ago

Whoa, @bedeho that was something, thank you! Also, @kdembler and @dmtrjsg thanks for the additional questions and adding new user stories, these are super helpful. As this thread becomes harder to digest with each new comment, I'll try to keep it brief for now:

Let us for the purposes of this product design brief leave aside: 1. How it is the council decides what to pay a given channel. 2. How often channels are paid. 3. What makes this payment activity economically rational or sustainable for the DAO. 4. The terms or semantics associated with the payments, e.g. whether it is per use, for the future, for the past, etc.

Am I right to assume that leaving this aside for the purpose of this conversation doesn't mean this information will not be publicly available to creators? I believe that some user onboarding to the concept of creator rewards directly in the app is very important, therefore I think it makes sense for us to have some visibility to the above. Also, I think it would be quite beneficial for the design team to know more about the overarching idea behind creator rewards regardless of anything. Can we find more information on that somewhere else? (I tried looking it up on GitBook my it seems like it's no longer publicly available; will reach out to you on Rocket about that)

As a channel owner I would like to withdraw tokens from rewards I've claimed previously

I just want to make sure I understand what do we mean by withdrawing in this case, from the end user's standpoint. Based on the "Who is paid?" section, is my understanding correct that withdrawn tokens are transferred from my channel account over to my personal account ("controller account of the member")? If that's correct, then what do I, as a regular member, do next? Basically, I'm trying to understand the complete user journey from the moment of claiming a reward to a point in which I'm using it to buy myself a cup of coffee offline.

Channel Viewer / Someone looking at a channel from the outside: Exactly the same as above, except no notifications and no actions for claiming/withdrawing.

Again, just to double-check I got that right: does it mean that any bypasser should be able to see an entire transaction and withdrawal history of a particular channel, directly on Atlas (eg. on a channel page)?

As a channel owner I would like to see the history of past successful events crediting my channel account, i.e. NFT sales, NFT royalties, successfully executed claims, and normal transfers.

As a content viewer, I can also make profits out of reselling NFTs, even though I don't own a channel, correct? Should I also be able to see the history of past successful events crediting my channel personal account?

bedeho commented 2 years ago

I am happy to do a call on the whole topic if that would be useful to everyone, and people can ask questions that are harder to generate just based on this dense explainer. Let me know.

Am I right to assume that leaving this aside for the purpose of this conversation doesn't mean this information will not be publicly available to creators?

That is largely up to you, but I think it makes a great deal of sense. Whatever you choose to do product wise, its important to have it be flexible enough to sort of work with whatever policy choice the council will end up using in the future, which is not entirely known. Some brainstorming could be warranted here.

Also, I think it would be quite beneficial for the design team to know more about the overarching idea behind creator rewards regardless of anything. Can we find more information on that somewhere else? (I tried looking it up on GitBook my it seems like it's no longer publicly available; will reach out to you on Rocket about that)

The idea is really quite mundane: platforms need to be able to pay creators for their work in some way, directly. It can't just be up to the creator to sink or swim on their own using digital asset monetisation. This is because of certain kinds of spillerover effects that happen in networks, which means that the network owner has a strong incentive to try to encourage people who make the network valuable. What the exact policy will be (e.g. based on views, based on one off deals, etc.) is not pivotal to this point.

is my understanding correct that withdrawn tokens are transferred from my channel account over to my personal account ("controller account of the member")?

Yes, this is correct. Basically cashing out refers to the act of redeeming funds that the council owes you, into your channel account, and withdrawing means moving funds from this account into a personal account. I have tried to be consistent about this, hopefully I did not mix them up anywhere.

If that's correct, then what do I, as a regular member, do next?

At that point the funds would be in a regular account you control, what you do with it at that point is up to you. You my want to hold it, you may want to sell it for some other assets, etc. This selling could occur for example directly p2p if you have a trading counterparty who is willing to offer you a good (e.g. like the famous Bitcoin pizza case) or service, or just some other asset, like cash or another crypto. Alternatively you may want to bring it to some trading venue like a decentralised or centralised exchange, where you can trade it for another crypto asset, or a stablecoin, etc.

does it mean that any bypasser should be able to see an entire transaction and withdrawal history of a particular channel, directly on Atlas (eg. on a channel page)?

Well, the system has this publicly available, whether its a priotity for us to incorporate this into the public channel view of Atlas is a different question, but I suspect yes that is a good idea.

Should I also be able to see the history of past successful events crediting my channel personal account?

As a content viewer you would not have a channel, so there would not be a channel account. If you are asking should I be able to see all NFT sales I have done, then that makes sense, but don't we already have this in some form?

dmtrjsg commented 2 years ago

Re Informed on Next payout date, not to miss the cash-out (1️⃣ )

The reason for this is to avoid the case where Channel Owner casually checks that channel is entitled to payouts, but does not claim at this point, returning in the future (in say 1week) just to see that payouts were reset to 0.

I understand the vehicle of payouts is proposal. We cannot predict/ have commitment on when the next one is. But what we could do here is.

  1. On proposal level affix some minimal required gracing period (e.g. 3days).
  2. On the Atlas side, have some UI element indicative on when the next payout date is due.
  3. If there are no active proposals for Payouts, then we just show 3d+ (knowing that proposal if created rn and approved will at very least take 3 days to execute).
  4. Once proposal is created, we would take the starting block time (if in the future) + Gracing period and show this as a base for countdown to next Payout (which may overwrite the owed / unclaimed values)

Re 2️⃣ - get informed as soon as budgets on council are positive and funds can be claimed

✅ great we can do it, perhaps not the highest prio but would be nice to aid channel owners in getting their funds when we can

Re 3️⃣ "Did not understand this."

The question comes from observation, that council does not rely on info about claims at the point of producing a new payload with payouts. Meaning.. if council budget for the purpose of payouts was insufficient between 2 separate payouts , then channel owners may face inability to claim payouts.

Here's an attempt to explain it based on timeline.

Point in time T => Council produces payout payload, channel owed balances = X. Point in time T+1 => Channel owner views payout balances but no funds in council so cannot claim payout. (X is owed to you, but you cannot claim it rn, wait till budget is sufficient) Point in time T+2 = > Council produces another payload, channel owed balances get overwritten with new value = Y. (Y overwrites X; or Y < > X+a) Point in time T+3 => channel owner views his channel account / payout page and sees new value Y, meaning that channel owner never had a chance to claim X.

Writing it up makes me think this is an edge case, since council will always have the budget for this in practice, but smth that could be possible..?

⏭️ a call would be helpful, perhaps we'd first need to sync up on our understanding, cut this epic into user stories with some Acceptance criteria and limitations and have a call based on the itemised list.