Problem 3. Re-entrancy bugs. Briefly explain what is an Ethereum re-entrancy attack and why
it can lead to loss of funds.
Problem 4. Tornado Cash & compliance. Tornado Cash is an app on Ethereum that enables
private transactions. In August 2022, the U.S. Department of the Treasury’s Office of Foreign
Assets Control (OFAC) added the Tornado Cash smart contract addresses to the Specially Designated Nationals (SDN) list, due to its usage for laundering more than $9 billion worth of
cryptocurrency since 2019, including by the DPRK state-sponsored Lazarus Group that was also
sanctioned in 2019. This designation forbids U.S. users, including individuals and institutions,
from interacting with the service.
In this problem you will design an alternative approach to mitigating usage of Tornado Cash for
illicit finance without completely prohibiting its continued use.
Let us first review how Tornado Cash (TC) works (simplified for the purpose of this exercise).
The app manages a Merkle tree M of cryptographic hashes called coins, a set N of hashes called
nullifiers, and a reserve of some ERC-20 token (e.g., DAI). There are two operations: deposit
and withdraw. In our simplified description users can only deposit/withdraw 10 DAI at a time.
When a user sends 10 DAI from an Ethereum address to the TC contract it also chooses two
128-bit random numbers (k, r) and provides the coin c = H(k, r), which the contract inserts into
M. It saves (k, r) as a note. When a user with note (k′
, r′
) wishes to withdraw 10 DAI to an
Ethereum address PK, it calls the contract’s withdraw function providing as arguments PK, a
nullifier nf
′ = H(k′
), and a zk-SNARK proof π that it has knowledge of a note (k′
, r′
) such that
nf
′ = H(k′
), c′ = H(k′
, r′
), and a Merkle tree membership proof for c′ in M. If π is valid and
nf′ is not yet in the set N then the contract adds it to N and sends 10 DAI to PK.
a. Why is the zk-SNARK π necessary? What could happen otherwise?
b. Why does this prevent a user from withdrawing the coin it deposited more than once? What
would happen if a user deposits only 10 DAI, and then attempts to withdraw 20 DAI?
c. When a U.S. regulated institution (e.g., an exchange) receives cryptocurrency from an Ethereum
address it must take reasonable measures to ensure it is not receiving illicit funds, e.g. funds
from an address associated with a sanctioned entity. There are services, such as Chainalysis, that provide institutions with risk scores for all public Ethereum addresses. However,
assigned risk scores to addresses that received a withdrawal from Tornado Cash is challenging: if Lazarus Group steals 5 million DAI from a smart contract exploit and dumps it into
TC, then every new address that withdraws DAI from TC may plausibly be associated with
Lazarus Group. How can a customer demonstrate to the exchange that its TC withdrawal is
not linked to the stolen funds? In your answer, try to minimize the information that needs
to be revealed to the exchange.
Problem 5. MakerDAO attacks. In class we discussed the MakerDAO system, where DAI is
intended to be a stable currency governed by MKR token holders. A brief description of the
MakerDAO system is available here, and a more in-depth description is available here. It is
recommended that you read one of these articles before answering the question.
Suppose that the MakerDAO pricing oracle (elected by MKR token holders) temporarily malfunctions and advertises that the price of ETH is $1,000, when in reality it is only $100.
a. How might an attacker exploit this situation to make money?
b. Assuming the error is corrected quickly enough not to destroy MakerDAO, who would bear
the losses from such an attack and through what mechanism?
Problem 6. ZK-Rollup limitations. Suppose that a consensus protocol (i.e., blockchain) running
among n participating nodes achieves consistency and liveness in a synchronous network, tolerating up to at most f < n/2 corruptions. To scale the throughput of this blockchain, we introduce
a powerful centralized server S that receives transactions directly from users. Given a current
state st of the blockchain and its Merkle root rt, S aggregates (potentially thousands) of new
transactions into a batch B, computes the hash h = H(B), the new state st
′ after applying all
transactions in B in sequence and its Merkle root rt
′
, and posts (rt
′
, st
′
) to the blockchain along
with a zk-SNARK π. The zk-SNARK proves knowledge of B and correctness of these changes
and hash values consistent with B.
a. Is it possible for users to verify just from looking at the blockchain itself that their transactions
(submitted to S) have been included? If not, how can the system be modified so that users
no longer need to trust S?
b. Why is it incorrect to say that this has scaled the throughput of the consensus protocol?
Hint: think about the definitions of consistency and liveness.
c. Let’s modify the design so that in addition S broadcasts the original transactions B to the
rest of the nodes participating in consensus. How does this change your answer above? Under
what assumptions might this increase the throughput of consensus?