Feedback request: a new staking UX in protocol proposal P

An upcoming protocol P proposal is currently in preparation and will include a revised version of Adaptive Issuance. In particular, a new API for the staking mechanism will be central to bakers’ and service providers’ UX.

The team would like to share the envision design of the new staking mechanism’s UX:

[Draft] New Staking UX Documentation

We kindly request that you use this thread to provide feedback, ask questions, and raise any concerns.

Please note that these documents describe work in progress and will be updated as the implementation evolves based on feedback received.


Re: unstake + finalise_unstake
There was much debate/discussion over unstake + finalise_unstake, in the aftermath of Oxford 1 failing. Wallet and indexer teams requested that we find some way to make finalise_unstake automatic and remove this second operation. Have the suggestions in the slack channel of how to achieve this been reviewed? Is there a breakdown of why each one won’t work / would cause issues?

Having the user required to complete a second action, means wallets will have to build a lot of UI around reminding the user, potentially having to integrate with calendar apps to set reminders, display annoying popups in app etc. From an end user point of view, its a unideal way to handle this

Re: unstake monitoring
Would it be possible for the unstake monitoring RPC to include a timestamp, as an estimate for when the cycle finishes? Wallets and tools will have to use this to display to users when they can complete their unstake, or when it will auto complete. Users don’t know “cycles”, and wallets don’t usually display this. Would be easier to have the server figure out the date once and cache it, rather than every client firing multiple requests to figure out where we are currently


Regarding finalize_unstake, I’ll let the team that worked on this reply in more details, but I can share some high level thoughts on it.

The transition function of a blockchain needs to run in bounded time, however, you may have a potentially unbounded amount of unstaking to finalize at boundaries, so you can’t just apply these automatically, or the chain could essentially stall.

So what are the options?

  • One is to ask the user to do it. This is the approach taken.
  • You could also make it implicitly happen when the user does something. That is implemented whenm thety call unstake. It could also be made it happen whenever they take any action of any kind, but that would require that every action taken starts with a if-then to check if there’s anything left to unstake, which adds performance overhead , some code bloat, and may be surprising behaviour to the user.

Some automated options

  • You could rate limit the ability of users to unstake so that there is always a bounded buffer of unstake operations to process. Probably a bad idea, there’s the kernel of something workable but most implementation could easily lead to users DDOSing the queue and preventing others to unstake.
  • You could keep a queue, and process it lazily: at the beginning of every block, grab 100 or so unstake operations to finalize and finalize them. There’s no telling if the number will make a difference and it also makes things somewhat unpredictable for users. Note that it’s always possible to implement this approach at a later time if deemed particularly useful.
  • You could schedule finalize unstake operations to happen not at cycle boundaries but at a fixed block offset from when the unstaking happened. This works but it means your block gas limit becomes variable, because you could need to process a lot of unstake in one block and none in another.

I do think the proposed workflow will require some work on the UX side, but I don’t think it needs to be reminders, popup or anything of the sort. A wallet can insert a finalize unstake operation as part of a batch when the user interacts with it and there’s a pending operation.


What error would a transfer operation produce when the seven cycles after the unstake operation have completed but the unstake_finalize operation has not completed?

If the error could include a hint that the unstake_finalize operation needs to be executed, then wallets could just include the unstake_finalize in a batch if both operations can occur in the same block or sequence the operations otherwise.

1 Like


Moreover, calls to unstake implicitly finalize all currently finalizable unstaked tez.

together with this

Requirements: amount >= 0

Makes in unnecessary for wallets to implement the finalize_unstake operation. Wallets could just call unstake twice, second time with zero amount.

For indexers it makes no difference. We have to reconcile all possible combinations of balance updates anyways. Challenge is to find all edge cases and construct test scenarios.


  • Slashing
    • Why are there two debit receipts from freezer/deposits for burned value (split between baker staker.baker and external stakers staker.delegate) but only one for reward (staker.delegate)? Is this just an oversight in the documentation?


Not issuing receipts (at least a single summary receipt) for unstaked_deposits slashes for external stakers at the time of slash (end of cycle), but instead delaying these receipts until finalize_unstake is opportunistically called by individual stakers makes global supply accounting impossible. Edit: probably misread, there is a receipt, so I guess finalize unstake receipts are just duplicates of that for individual slashed unstake requests.


Since there is a new set_delegate_parameters operation, there is an opportunity for bringing in more parameters that currently have their own operation.

Namely, setting the consensus key is done with a dedicated operation. This operation update_consensus_key could be deprecated, and the consensus key updates done with set_delegate_parameters.

Also, there is an opportunity to add a new delegate parameter: destination account for delegation rewards. This would simplify baker operation. I’ve written a post about it.

Will the core teams please consider these improvements?


Thanks for sharing your concerns.

As explained by Arthur, our design choices were shaped by considerations of efficiency and security.

Unstaked funds cannot be made liquid immediately, and automatically handling delayed finalization as an internal maintenance task was not deemed reasonable.

The best improvement in terms of user experience (UX) we could offer was to automatically trigger finalization during stake/unstake operations. While we could have incorporated finalization into every operation, this would have incurred a gas overhead for all accounts, whether they were stakers or not. Therefore, we chose manual finalization at the protocol level.

Thank you for your suggestion.

While including a hint in the receipt to execute ‘finalize_unstake’ would be equivalent to performing the computation in terms of cost, the protocol cannot provide such a hint. Instead, we expose the finalizable amount through an RPC, allowing external tools to autonomously provide the hint.


automatically handling delayed finalization as an internal maintenance task was not deemed reasonable

FYI, the last comment in relation to this in the slack channel, was the wallet and tooling teams being told that there was previously a mistake in the communication, and that it already was automatic. finalize_unstake was only needed to ensure the unstake happened in a specific block. If ignored, it would be auto unstaked in a later block. I for one was under the impression that this was going to be delivered as an automatic option. I think any changes to this process really should have been discussed sooner with the teams in an ad-hoc manner, to see if theres any other ideas, if trade offs are acceptable etc. Depending on how much gas is needed to perform this on every block, if its a small amount, users may prefer this. Advertising that this is all handled automatically and you never need to worry, is a selling point that can be pushed on social channels. Compared to having to set a calendar reminder for yourself to check if its ready or not, finding out the cycle end date has moved, setting another reminder etc

If we are going down the road of making users/wallets do all of this, can we at least add something to the run_operation / simulate_operation response that indicates there is a pending unstake ready for finalisation? Similar to the flag that indicates a reveal operation is needed?

The process of performing a full estimation, and handling all the edge cases is already overly complex and requires lots of business logic to ensure it goes through smoothly. If theres an expectation that wallets should be performing finalize_unstake automatically, adding more RPC calls to the estimation flow adds a lot of burden on wallets and tooling. A flag that indicates it should be added would at least minimise the logic needed

Re: Alex’s comment above. Is calling unstake with a value of zero, the same as finalize_unstake? If so, why do we need 2 operation types? Can we not just keep unstake and make things simpler?

Is there an opinion on my second point above? Can we add timestamps to the monitoring RPC to avoid wallets having to do this logic on every request?


If funds are finalize-able, but a user ignores it for a few cycles, and then a slashing event occurs. Will the finalize-able funds be affected also? Would the user suffer a slashing event that they otherwise wouldn’t have if it was automatic?

As a user, we would prefer this, from far.

1 Like

The hint be added by the indexer, simplifying the work needed in the wallets.

Thank you for bringing this proposal to our attention.
We would like to focus on the currently proposed features before adding new ones. Rest assured that we will consider this proposal in line with our priorities for a potential future protocol proposal.

Regarding the usage of unstake with an amount of 0 to trigger finalisation, we liked to draw your attention to the fact that you would pay more gas than by calling finalize.
For slashing receipts, we can admit that the names are a bit misleading, but there is no oversight in the documentation.
The confusion arises from the fact that the “deposits” category is not structured as the “unstaked_deposits” category. While “{delegate : pkh }” in “deposit” refers to the sum of delegators only, “{delegate : pkh }” in “unstaked_deposits” refers to the sum of delegators and the delegate.

Thanks Zaynah, interesting but not 100% what I meant. I can’t copy from the google doc, so you have to follow my pointers:

The example in section “Denunciation and Slashing” displays 7 balance updates. I start counting from 1.

The offender penalty amount is taken in receipts 1 (from stakers) + 2 (from unstaked stakers) + 3 (from baker stake).

The accuser reward amount is taken in 5 (from stakers) + 6 (from unstaked stakers).

No reward is taken from baker stake unless balance receipt 5 has a different meaning than receipt 1. It should not have a different meaning because its impossible to know because 5 has the exact same structure/content as 1.

1 Like

Thanks Alex for the feedback, we have corrected the receipt for the denunciations in the document which as you pointed out was incomplete.

1 Like

Sorry for the misunderstanding. The proposed automation was for pre-AI activation, as it only requires iterating over active bakers, which is currently fine.

Regarding UX, the Octez node has an RPC that exposes the currently finalizable amount of tokens and the amount of tokens that are not yet finalizable, together with the cycle at which they were unstaked (see here). From the cycle of unstaking, you can easily compute the first block where the tokens will be finalizable.

Also, please note that as long as users don’t use their funds, there’s no need to finalize, and actually, the user should not systematically finalize their unstake request the moment they are available. If they don’t need to transfer their funds, it doesn’t bring them anything to finalize them, and they will pay fees only once if they finalize multiple unstake requests together. So, I don’t think you need to remind a user to trigger a finalization. You just need to display the finalizable funds when the user looks at their wallet


So, I don’t think you need to remind a user to trigger a finalization

This is not true. Users will be very unlikely to initiate an unstake operation, with no intention to do anything with it. A user who unstakes, wants to do “something” with their funds. Having a long running operation with no indication of its progress, or reminders that its ready is very poor UX, guaranteed to generate complaints from end users.

Can you answer my previous comment? if the user “forgets” to finalise_unstake, and a slashing event occurs, would the unstaked funds be slashed?

1 Like

Hi Simon,
That’s what Zaynah was implying when she says that

it doesn’t bring them anything to finalize them

Finalizable unstaked deposit are not slashable, and that’s why there’s really no point to trigger a finalization as long as you don’t need the funds for something else.

1 Like

We just examined the current changes in regard to how they’d work with TezPay. We struggle to figure out how to get the portion of rewards generated from the delegated balance. Please help us understand how we can support paying delegators in cases where the baker uses a non-default staker edge.

Delegated funds are affecting just the rights but are excluded from reward distribution. Additionally, by splitting how rights are assigned and how rewards are distributed - snapshot vs current balance - we wont be able to tell apart what belongs where.

In P there wouldn’t be stake snapshots any further, and rights would be computed at the end of the cycle, once Adaptive Issuance is enabled. We are both concerned that in P, while AI is not enabled, at the intermediary stage, as well as in the final activated stage, we wouldn’t be able to distinguish between staker and delegator rewards if the baker is using an edge other than 100%.

Can someone help guide us on how to distinguish delegators specifically in a case where baker has staking edge set to say 50%?

Here’s the Gitlab issue where this subject is tracked: AI: do something for reward distributors (#6099) · Issues · Tezos / tezos · GitLab