Ah yes, ACK on shadow chains.
I don’t think this reduces to CoinJoin? It’s non-interactive and asynchronous. The functionality is more like a ring signature mixer. But it clearly can be simplified, perhaps by just dropping the entire Plasma mechanism and storing everything on chain for now. (In which case I should change the post title and category…)
The contract would be initialized by a depositor, who would prefund it with some substantial amount. The contract would maintain a mapping of commitments (salted hashes of public keys) to balances (and commitment times).
Anyone can call deposit at time T1, specify a new commitment, and pay in X ETH to add <commitment>: (X, T1) to the mapping.
Some time later, someone can call initiateWithdrawal. They put down some deposit, specify a destination address, and specify a list of “inputs”. Each input includes a public key (which is purported to correspond to some committed public key in the mapping), an amount, and a signature from the public key on the rest of the data in the transaction (best way to do this to be determined). This is stored as a pending withdrawal (along with the time at which it was submitted, T2). The public keys used are added to a blacklist, meaning they can never be used in an input of a withdrawal again.
After some time, a randomness beacon resolves, and one of those inputs is chosen to be audited, with the selection weighted by the amounts in each input. The withdrawer can then call completeWithdrawal and reveal the salt for that input, showing that that public key was committed to in the mapping before time T2, and that its amount was greater than or equal to the amount asserted. The commitment can then be removed from the balances mapping.
If the audited input was in fact fraudulent, the depositor will not be able to reveal a commitment in the balances mapping that matches it, and will lose their deposit along with any balances in other inputs that were valid.
The fees and withdrawal deposits can be tweaked to discourage fraud and make it worthwhile for the initial depositor to fund the backstop, without hurting the level of anonymization enjoyed by honest parties.
There are some pretty obvious ways to make this more efficient (and it’s already not too bad; it improves significantly on both the bandwidth and computation requirements of ring signature mixers, though it seems to have the same unfortunate storage requirements). But I’d be curious if there’s a way to improve the anonymization, maybe by combining it with some other mechanism. The properties this provides (unlinkability of outputs, except to one randomly selected one of the inputs) are a bit too quirky for practical use as a tumbler.