### 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.