### We need a first step toward more privacy Currently there are large privacy problems in the ethereum ecosystem. The default behavior is to do everything through a single account, which allows all of a user's activities to be publicly linked to each other. It seems like this can be improved by using multiple addresses, but not really: the transactions you make to send ETH to those addresses themselves reveal the link between them. This greatly hinders adoption of many applications, eg. see this thread on HumanityDAO: https://twitter.com/Mooncritic1/status/1127544338408300545 A simple mixer for sending fixed quantities of ETH from one account to another without the link being visible on-chain would be a great first step in alleviating this. Even if the quantities of ETH it targets are small (eg. a fixed denomination of 0.1 ETH) it could go a long way in enabling privacy-preserving usage in the many applications that do not involve large quantities of funds but need some ETH to pay for small-scale security deposits and/or application and particularly transaction fees. ### Minimal Mixer design On-chain, we create two contracts, the **mixer** and the **relayer registry**. The **mixer** has two functions: * deposit(bytes32 commitment) payable verifies that DENOMINATION ETH (eg. 1 ETH) was sent along with the call, and if so it adds the commitment to a list of commitments. It also maintains a Merkle tree of all commitments to far that uses some SNARK-friendly hash function (even Pedersen to start off would be ok). * withdraw(address destination, bytes proof) verifies that (i) proof is a valid ZK-SNARK that proves that destination and some commitment in the tree are related to each other (eg. destination = H(commitment + salt)) but does not reveal _which_ commitment the witness corresponds to, and (ii) destination has not yet been used. Upon success, it pays out DENOMINATION - FEE to the destination and FEE to msg.sender FEE is a parameter that adjusts in a sawtooth-like wave function, eg. FEE could be the cost of executing a withdraw call at 0.1 * 1.0722 ** (block.number % 100) gwei (this is a repeated exponential curve that starts at 0.1 gwei and ramps up to 99 gwei). This is basically an ascending-price auction for getting any withdrawal requests included. The **relayer registry** is a simple contract where anyone can publish their IP address for a small fee (note that this could be re-used for other applications and not be mixer-specific). --------------- The default behavior for someone participating in the mixer is to send a transaction to deposit, wait some amount of time to get a larger anonymity set, then generate a proof and ping it via an HTTP POST request to each of the IPs in the registry. The goal would be for the client-side software (calling deposit, generating proofs, sending the proofs to relayer) to all happen in-browser, so that this application can live purely as a static page inside of a browser. SNARK proof generation could ideally be compiled into WASM and run in the browser as WASM, HTTP POST requests could be done cross-domain via techniques like in https://stackoverflow.com/questions/298745/how-do-i-send-a-cross-domain-post-request-via-javascript. The server would likely need to be written in node or something similar. The goal would be to have a look and feel similar to Uniswap, except instead of being for exchanging tokens it would be for making private sends.