SunkETH

Make private transfers indistinguishable from regular ones! A token implementation of "Zero-Knowledge Wormholes" described in EIP-7503

  • 645 Raised
  • 220 Views
  • 1 Judges

Categories

  • ETHDam - Privacy Track

Description

Contracts, circuits & frontend 👉 https://github.com/kevincharm/i_lost_my_eth_in_a_boating_accident

Deployed SunkETH contract: https://sepolia.etherscan.io/address/0x46cfe55bf2e5a02b738f5bbdc1bdee9dd22b5d39

Example reminting transaction with ZK proof-of-burn: https://sepolia.etherscan.io/tx/0xda33a40dc4c9cd1aa0e3881db9e5fcb580ed0f078d27cb030bd796ad1974d3fb

Example unspendable address: https://sepolia.etherscan.io/address/0xe175aB294bCA5cC767Ef8Cf58A0F287C7f43c342

SunkETH works like WETH, but supercharged with zero-knowledge wormholes (https://eips.ethereum.org/EIPS/eip-7503). Using some cryptographic tricks and with the help of ZKPs, we can create private transfers that are indistinguishable from regular transfers.

Making token burns indistinguishable from regular transfers

At the heart of zero-knowledge wormholes is the verifiably-unspendable address. We can define an unspendable address by taking the preimage resistance property of keccak256 s.t. given random number $r$ and $keccak256(x) = r$, we cannot feasibly compute $x$.

Importantly, we need to ensure that $r$ is truly random. So if we take another hash function different to keccak256 (e.g. sha256) and treat it as a random oracle, then we cannot know $x$ where $keccak256(x) = sha256(s)$. Therefore address $A_u = keccak256(x) = sha256(s)$ is unspendable.

Zero-knowledge proof of burn

Using ZKPs, we can prove knowledge of $s$ without revealing $s$ and only revealing $A_u = sha256(s)$. This means we can prove that we transferred funds to a verifiably-unspendable address, and it would be safe to *re-mint* the transferred amount, at a new arbitrary address.

We use aragon's noir-trie-proofs (https://github.com/aragonzkresearch/noir-trie-proofs) circuits to create state and storage proofs, while hiding the storage key, thus never revealing $A_u$. The state proof is verified against a state root, which is extracted from an RLP-encoded block header that corresponds to a recent known blockhash (it can be any block after burning tokens to an unspendable address).

The state root proves the SunkETH contract account state, which is RLP-encoded data that includes the account's storage root. We privately prove that the storage root is correct using a storage proof as a private input to our circuit - this hides the storage key, which hides unspendable address.

Attachments