What do we do about legacy value pools?

In the original launch of Zcash we introduced the Sprout shielded protocol. In the time since, we’ve deployed a new shielded protocol called Sapling which uses a different value pool. There is basically no reason to use the original Sprout shielded protocol and its expensive proofs, and so for years the default in our software is to offer Sapling addresses. We’ve been encouraging users to migrate their Sprout funds to Sapling. Community projects at this point solely target Sapling support.

As of this post the Sprout shielded value pool apparently has 110640.29858694 ZEC in it, which is over $6M dollars worth of coins. In an effort to further encourage migration of these coins, the upcoming Canopy upgrade will make it impossible to move new coins into the Sprout value pool. This will probably not be enough to flush everyone out; a huge portion of these coins may be in discarded wallets and lost keys.

Sprout is the first example of a legacy value pool. It’s been deprecated and nobody uses it seriously, that we know of. However, it remains in the protocol. Nodes still have the code to verify the rare Sprout transaction that appears on chain. This code needs to be maintained, as well as the wallet code necessary to make Sprout transactions. This is a perpetual burden on development and continually increases the risk of consensus forks and security bugs. We’d really like to get rid of the pool entirely some day.

However, we’ve never established an expectation among our users about how long a pool will be supported before we pull the plug on dormant coins. Imagine someone buying some ZEC back in 2016, watching ZEC moon (as we know it will!) and then trying to dig up their old shielded wallet. Surprise!


The idea of destroying dormant value is extremely controversial in crypto communities. However, if we set the expectation that long term cold storage in shielded protocols isn’t supported and that mandatory turnstiles should be expected, it’s fair game. We haven’t done this yet, or even had a conversation about it.

There may be some alternatives to destroying the pool. Perhaps we could create a sidechain-like thing which runs the Sprout protocol and punt the maintenance burden to the interface between the chains? Or you could have some kind of organization take custody of the pool and be responsible for maintaining/distributing the coins to people who show up with Sprout proofs.

More radical proposals include destroying the pool and redistributing its funds to miners or airdropping it on the community. Some might argue that having more confidence in the monetary base makes market capitalization a more useful economic indicator.

In any event, let’s talk about what to do because this probably isn’t the last pool that we’re going to want to get rid of and we need to start setting expectations.


What’s the point of destroying the pool? Remember it doesn’t exist as some kind of entity. It is a group of transactions moving money into the pool (and you can’t delete those, they are on the blockchain) - and a group of transactions moving money out.


The Sprout value pool is an isolated total of money sent “into” the Sprout protocol but not taken “out” of the Sprout protocol. Assuming the integrity of the Sprout protocol, it represents the outstanding value of unspent Sprout notes. Ideally we could turn off the Sprout protocol itself to simplify Zcash development, as Sprout is deprecated, but there would still be a pool of >100k unspent ZEC sitting in the Sprout tree that people may or may not have the spending keys for.

We have to figure out what to do with that pool.

Ideally we could turn off the Sprout protocol itself to simplify Zcash development

This isn’t possible on the code level - a node must be able to verify all blocks up until the current time. So it must be able to “understand” Sprout transactions indefinitely.

Even deleting the pool won’t give any savings in code or time to verify since that would mean marking those “incoming” transactions as unspendable. They will still be on the blockchain, and will still need to be verified by the future nodes.

1 Like

This isn’t what I’m referring to, but it’s not true either. We don’t need to verify Sprout transactions forever. We can assume that they’re valid and hardcode checkpoints into the codebase. In fact, we do something like this already; in zcashd (and I think in zebrad as well) we don’t actually verify pre-Sapling BCTV14 proofs and have removed libsnark from the codebase. We assume they’re all valid prior to Sapling, because they were.

My actual desire is to be able to remove the ability to create new Sprout transactions. This is effectively what I mean by “turning off the Sprout protocol” and it has a huge impact on code maintenance. It means we can remove Sprout wallet functionality. It means we can remove consensus rules related to Sprout, and it means new consensus rules don’t need to take Sprout into account because those functionalities have been entirely removed from transactions.


On that I agree, that’s a straightforward no-brainier.

What about leaving open the potential for a process by which you can still claim an old sprout utxo, but in a way that isn’t high priority so it’s slow and difficult and hopefully never used, but the door isn’t necessarily shut forever?
One example: you could reveal in plaintext the commitment for the utxo in the tree, then you wouldn’t have to rely on the old snark parameters?
As another: could leave such transactions as invalid/unsupported under current rules but leave open the opportunity to add support for them in future updates if some transactions…

Basically withdrawing an unsupported legacy transaction could take as long as an entire development update cycle, but can be considered possible


As a starter, all wallets can start notifying users to move from sprout to sapling. Or even a single button to move value or doing that automatically.

1 Like

I don’t like the idea of destroying value. Many will agree with me. Let’s discard that idea, that idea is only going to get hate from other communities (zcash gets enough hate already!)

1 Like

I forgot to add - I stand corrected on that point then. Thanks for pointing that out :slight_smile:

There is one usecase for creating new outputs of old proofs that nobody considered yet. That is is if I’m up to no good and I found an exploit in the old code. Reducing surface area for attacks should be considered as a “pro” to getting rid of the ability to create them.

1 Like

Is there a way for users to auto-upgrade so they don’t need to make any action, things will just “work”.

The turnstile tool is pretty simple, just run “zcash-cli z_setmigration true” and it does it for you, but yeah that is an action to take


Just to be clear, I knew I was asking a dumb question but I had to ask. Andrew, I’m aware of migration tool but usage of that tool is not mandatory, some users may not even be aware of that tool.

Is hardforking a feasible solution? It will motivate people to use whatever tool available to get new tokens (edit: value of old token may not be zero, because users can convert old token to new token)

That’s a sure way of making sure there is no tech debt & users using safer, better tech

There is a bit of a privacy and authentication leak here. In order to authenticate ownership of the note you need to essentially reveal the incoming viewing key. (Perhaps this could be done in zero-knowledge, but then you’re back to using SNARKs anyway.) If you didn’t authenticate then people could steal your money in transit. Also, the note contains both the address and other details known to someone who paid you, so you might leak your identity.

I think if we continue down the route of allowing people to redeem long-lost funds in Sprout, we should stick with just using the SNARK to make it as private as possible. It’s just a matter of where (and who) is verifying the SNARK proofs.

This is interesting. Essentially, you need to wait in line and at network upgrade boundaries we’ll take batches of transactions and move them through the turnstile. We only need to make sure that the turnstile is maintained and only need to enforce Sprout rules at those boundaries, instead of enforcing the Sprout rules continually. It also might be an opportunity for us to impose “maintenance fees” of some kind.


Ah, but who is “we”? If this is done by a discretionary network upgrade driven by some entity, rather than decentralized consensus code, then whoever is driving this process is plausibility “touching people’s money” by including these transactions. This opens a deluge of liability and regulatory concerns. Is this entity now a “money transmitter” or “VASP” subject to AML rules? Does it need to make sure the migrated funds do not go to, say, someone on the OFAC sanctions lists?


People in the crypto space will be familiar with ICOs that had deadlines for redeeming.

I think the idea of destroying or airdropping is a good one as long as there’s sufficient lead time and some research to ensure likely ZEC early adopters have been adequately informed, and some flexibility as to the deadline if there are any concerns about this.

And if you were going to do this, the sooner you announce it the better. Giving people 3 years or 5 years feels pretty safe, and that at least sets some limit on how long these transactions will have to be supported for.


If we are taking this route, then I’d recommend same path for t-address (stop support for t-addr completely) in X years.

1 Like

(Not speaking for ECC.)

I would personally support destroying remaining Sprout funds in NU7 (scheduled for mid-2022), as long as this passes a simple-majority Community Panel vote more than a year in advance. The security rationale alone is compelling. (Note that I’m not aware of any security flaw in Sprout, but the risk of such a flaw is not negligible.)

Before that, we should restrict Sprout transactions in zcashd to migration transactions, and maybe enable migration by default.


Is there a way to have Zcashd detect old Sprout addresses and force migrate the funds to a new Sapling address in the same wallet? It’s not very democratic way to get users to upgrade but it would be better than destroying funds.


If Zcash removes the remaining Sprout pool, I imagine users will never use shielded pools except for unsafe Quesnelle-style passthroughs. And I don’t blame them; no one wants their funds to be destroyed.