Busses and service changes

Lasse Herskind
HushHushEth
Published in
5 min readFeb 28, 2021

TLDR: Hush Hush introduces the Bus Station, a micro-rollup that reduce gas-usage from 1 million to 165K (23$ at 100 Gwei) for each deposit. To support this and to improve simplicity and anonymity, we remove arbitrary withdraws.

As noted in our first post, the Hush Hush system’s gas usage was quite significant and could easily price out smaller players. To combat this, we have in the last week been exploring more snark computation and the utilisation of micro-rollups to reduce the cost of depositing. Unfortunately, the rollup structure doesn’t play well with the variable withdraws, which means that we discard that feature moving on. This is done in part because of the rollups and in part because it allowed the user to reduce their anonymity significantly if used improperly.

For this post, we will introduce our findings, and their impact on the gas used to improve on-chain anonymity.

Small overview of the gas costs of different interactions with Hush Hush and the Bus station. Top half is direct interaction with a Hush Hush pool, and bottom with the Bus station. Assuming 100 gwei and Eth price = 1300.

The results outlined in this post is based on a simple ERC20, and the gas prices is expected to increase a tiny bit for Aave aTokens for the computation of scaled balances. Some measurements are visible here, with expected cost in $.

The first step to reducing the cost of depositing is relatively simple, instead of updating the path of the merkle-tree on-chain by computing a lof of expensive hashes, we broadcast the inserted commitment, the new root and prove that the old root with the commitment inserted gives the new root. In short, we prove that we have done the hash-computations and that the new root is indeed the result. Doing so let us cut the 1 million gas down to 372K for a deposit. While this is a significant reduction, it is not for free. Hence the proof is only valid for the specified “old root”, a change in the on-chain state between proof generation and transactions execution would mean that the transaction is reverted. In short, this means that if somebody else deposits with a higher tx-fee than you, he may make it such that your transaction is reverted. In practice it is possible to censor certain people from depositing if an attacker updates the state every time they try to do so. Nevertheless, an attacker cannot censor the withdraws as those do not update the tree. In short, an attacker can keep you from entering but not from leaving.

Because changes to the tree will revert, someone could unknowingly increase the latency for another user, which is not that great. To combat this issue and reduce the cost further, we can group multiple deposits into a larger state-update. This concept of grouping transactions is often known as a rollup, e.g., you roll up a couple of transactions and proof that they are valid + their changes to the state.

For those unfamiliar with the rollup-concept, think of it as driving on a bus instead of in your own car. In your own car, you can decide exactly when to go for a ride, but you have to pay for it all yourself. On a bus, you don’t control the time to drive yourself, but you can split the gas-cost between the people joining the ride. In Hush Hush, we will have a bus-station, allowing the user to buy a ticket for the pool of their picking, splitting the gas-cost with the other passengers. Anyone with a bus (sufficient eth to do the deposit), can then pick multiple tickets from the station and drive them to the pool. As payment for his service, the driver receives a fee from each ticket.

The bus station. Here shown with 3 transactions, the third having multiple “sub”-transactions.

The current bus contains 8 “seats”. The bus size is based on the frequency of deposits in Tornado.cash thereby ensuring that they can ride “often” enough for the system to be useable while still bringing a significant discount.

At the bus-station any user can buy a ticket (~45K gas). The ticket contains a commitment and a user-defined fee along with the users address. The user must also approve the bus-station to spend his tokens for it to get the funds for the deposit when necessary, an approval is often ~45K gas. To figure out what fee to include, we must first look at what it shall cover.

A bus-driver comes along and picks up to 8 tickets from the bus-station that he wish to transport. He will generate a proof for the multi-deposit and call driveBus at the bus-station with this proof as input. The bus-station will then pull depositAmount + ticketFee tokens from the ticket owners account. The depositAmount is inserted into the pool, and the bus-driver receives the ticketFee for his service (only if the proof is valid). As long the sum of the ticketFees > tx-fee he makes a profit. Currently, driving a bus with 8 seats costs ~587K gas. Meaning that the gas spent per deposit is 73K. While this gas-number is quite nice, it becomes even better if users who anyway would have paid for the full deposit themselves (372K) decides to pick a couple of tickets along with them, for the extra 215K gas we get 7 additional deposits.

The cost of depositing when using the bus-station should be expected to be approx: approving funds, buying a ticket and the fee to the driver ~ 45K + 45K + 73K ~163K Gas. And if you make a larger approve, it could be ~118K gas for future deposits. At 100 Gwei, that is around 0.016 and 0.012 eth.

A high-roller can also use the bus by himself, making 8 deposits at once, because he can do so directly to the pool and does not require multiple token transfers, he can do so for ~450K gas.

A bus-station can also be run entirely off-chain. By using permits and signatures from the users the bus-driver can provide all necesseray information to the contract, thereby supporting gas-less transactions where the fee is paid directly in the underlying asset.

Withdrawing

Because the withdrawal of funds requires secret knowledge, we cannot do a bus as easily as we could for deposits. This means that the current cost of a withdrawal is ~350K gas.

However, last Monday, the Aztec team presented at the ZK-Sessions that they could verify a proof inside a proof without gigantic circuits. Verifying proofs inside other proofs is a huge step forward, and means that it is possible to build rollups of other snarks, e.g., a rollup of withdraws. But it could also be used recursively, such that you have a rollup of rollups.

At Hush Hush we are excited about these constructions and will investigate how we can use them to create anonymous on-chain savings accounts at a low cost.

Recap

  • We throw away the idea of variable withdraws
  • We reduce deposit cost significantly, supporting deposits at <25$ each.
  • Withdraws are still expensive

To stay updated on the progress of Hush Hush, you can follow us on twitter: @HushHushEth

--

--

Lasse Herskind
HushHushEth

Engineer working on improving privacy on Ethereum