There are already several possible designs for this, that I’ve been discussing with other Zcash protocol devs (on the side at conferences, in dev calls, and in spare time) as the next step for Sprout deprecation (as well as a model for future pool deprecation).
- If we as a community want to pay the cost of Sprout logic in consensus forever, then the remaining Sprout funds are frozen, and a Sprout redemption circuit replaces the current Sprout logic, using a value balance mechanism compatible with one of the non-deprecated pools (i.e. Orchard).
- I suggested this 4.5 years ago: What do we do about legacy value pools? - #56 by str4d. No one has taken action to productionise it in the intervening time.
- Redemption actions would be distinguishable on chain, just like Sprout transactions are currently distinguishable from non-Sprout transactions, so there’s no change there. Redemption values would be hidden, which is an improvement.
- This requires paying for a new circuit to be written, reviewed, audited, and deployed.
- If we wanted the redemption actions to be indistinguishable from other actions, that would require recursive proofs, which are not currently present in Zcash consensus and thus would require additional time and funding. And given that the status quo doesn’t have this, I don’t see the benefit outweighing the complexity (at least for Sprout deprecation).
- Once ZSAs are deployed, another option is that the remaining Sprout funds are frozen and then turned into a ZSA.
- Conversion from frozen Sprout to the “synthetic Sprout ZSA” would be done off-chain by users presenting a proof (probably reusing the current Sprout circuit) to a trusted group of orgs via a multisig.
- The Zcash community should be fine with this trust model; the Dev Fund lockbox contains over double the amount of ZEC left in Sprout, and there was clear support for the Coinholder-directed dev fund model that uses a similar trusted group of orgs for disbursing funds.
- The Sprout logic on-chain would be replaced with a small consensus rule that permits users to reveal and burn N units of “synthetic Sprout ZSA” in order to move N units of ZEC from the frozen Sprout pool’s remaining balance (to any currently-active pool). This replaces the current turnstile between Sprout and the other pools.
- A user who wants to avoid the turnstile, could instead trade their "synthetic Sprout ZSA"s for ZEC inside the Orchard pool (to a counterparty who is happy to cross through the turnstile). This would reveal the moved amount to the other user (or DEX or whatever mechanism is used) instead of publicly on chain, same as with any regular shielded payment.
- The redemption process should have a (widely publicised) redemption window (e.g. several years). Once that window of time ends, the trusted group of orgs could use the ZSA finalization flag to ensure that no more "synthetic Sprout ZSA"s can be issued, at which point any remaining frozen ZEC in the Sprout pool (which would primarily be ZEC stored in lost keys/wallets that can never be moved) could then e.g. be unissued via the NSM (and thus returned into circulation via the block subsidy, funding network security and development).
- Another way to incentivise redemption that I’ve seen suggested before is to have the redemption “exchange rate” include the cost to the network of the legacy pool, by having two outputs from each redemption action (one issuing the synthetic ZSA at a reduced exchange rate, the other moving the remainder of the ZEC into the NSM). In this design, the exchange rate would decrease from 1.0 to 0.0 over the redemption window (either continuously, or in several steps at well-defined times). Once the exchange rate reaches 0, any redemption would result in all funds going to the NSM, which provides the “window end” cut-off point.
- Even with a redemption window, the Sprout pool balance would not be guaranteed to go to zero under the above process, because someone could go through the redemption process to obtain "synthetic Sprout ZSA"s and then lose access to their wallet before they convert them back into ZEC. This could be handled with a separate “conversion window”, which could be e.g. a consensus rule like “synthetic legacy pool ZSAs will only be supported until the subsequent 2 pools are both also deprecated, and then they can’t cross the turnstile into a ZSA-supporting 3rd pool”.
- This would mean that the effective “lifetime” of Sprout could end up being several times longer than its “active lifetime” (which was 4 years; the network prohibited moving funds into Sprout in the Canopy NU in 2020).
- By using ZSAs as the base for this, the cost of deprecating legacy pools is much lower (as they can all reuse the ZSA circuitry and logic as it exists in whatever is the current pool), and it could be specified as the deprecation process for all current and future pools (because it just requires the concept of ZSAs to continue to exist in Zcash) which would provide certainty for users going forward.
- Conversion from frozen Sprout to the “synthetic Sprout ZSA” would be done off-chain by users presenting a proof (probably reusing the current Sprout circuit) to a trusted group of orgs via a multisig.
(I started writing the above at 1am and it’s now past 2am; hopefully it isn’t too rambly!)