The short answer is: after an association set update, previously generated proofs usually cannot be used. This is true if the old association set root (aspRoot) bound to the proof has been replaced by a new version.
This is not the protocol targeting any user. It is simply how withdrawal proofs are designed: they can only match the on-chain state at the moment they were generated.
Why old proofs fail — the proof "locks in" the association set root at that time
Privacy Pools withdrawal proofs need to verify two things: first, that the deposit commitment is in the state tree; second, that the deposit's label is in the association set tree. The association set tree root (aspRoot) is bound into the generated Groth16 proof as a public signal.
When the contract verifies, it checks whether the aspRoot carried in the proof matches the root currently published by the ASP (Association Set Provider). If the ASP updates the association set (for example, removing a newly discovered illegal deposit), the aspRoot recorded in the contract changes. The old proof's aspRoot no longer matches, so verification fails.
Does it always completely fail? — It depends on the situation
In most cases: If the association set update only adds new compliant addresses, old proofs likely still work, because the old aspRoot may still be in the contract's accepted history. The contract stores several recent state tree roots and association set roots to avoid proofs failing from a slight lag.
The core risk: If the update involves an "exclusion" — for example, an address in the set used to generate the proof is later marked illegal by the ASP — the proof may still pass verification, but the "compliance signal" itself becomes diluted. Outside observers cannot tell whether your deposit belongs to the group that was removed.
Practical advice: do not generate proofs "in advance" as a backup
If you plan to deposit first, generate a proof now, and submit it later when you need to withdraw, that strategy does not work in Privacy Pools.
The association set is dynamic. The ASP continuously monitors on-chain transactions and updates the set regularly. Just because a deposit is clean at the time of deposit does not mean it will still be clean when the ASP next updates. If you generate a proof in advance, by the time you use it, the ASP has probably updated and the old proof likely will not work.
The correct approach is: generate the proof when you withdraw, not before. The aspRoot used must be the latest version.


