Tornadoxxed 👀

ETHBerlin3 Hackathon Project

Team: @hildobby, @Ktl-XV, @sui414

Website: tornadoxxed.xyz
Twitter: @tornadoxxed
ENS: tornadoxxed.eth
Github: https://github.com/tornadoxxed
Dune Team Page: https://dune.com/tornadoxxed

Our Initiatives

We aim to:

  • Bring Data Transparency Remove the data availability barrier, so to help any Ethereum wallet owner to check if their wallets are involved - awarely or unawarely - in Tornado Cash transactions.
  • Open-sourcing Address Detection Methodologies Defined potential basic heuristics that can recognize wallet behavior patterns, and alert the risk.
  • Privacy & Security Education Therefore this website serves as an educational showcase of how users should not be using Tornado Cash, i.e. the behaviors which may leak privacy information.

We strongly believe that Tornado Cash is used by good actors and we want to help showcase what you shouldn't do if privacy is your concern. This website showcases how we were able to find over 100 depositor to withdrawer address matches based on how much they deposited and withdrew amongst the pools. This is a proof of concept and other patterns can be added to expand this database and lookup tool. You can also check all Tornado Cash transactions that a speicfic address has done by either searching it, searching its ens name or connecting your own wallet.

What We Built

A website that supports:

  • Tornado Cash Transactions History Lookup
    • inclduing deposits and withdrawals
    • data coverage
      • across 6 L1s/L2s (Ethereum, Optimism, Arbitrum, BSC, Avalanche, Gnosis)
    • multiple lookup methods
      • wallet address
      • ens name (support w/ or w/o .eth)
      • wallet connecting
  • Address Linking Risk Detection
  • Address Balance Clearing Pattern Detection

Heuristics

Address Detection

Heuristic 1: Depositor <> Withdrawal Linking ✅ (implemented)

  • Check each depositor (or withdrawal) address's action in each size of the pool, note as \([d_i] (or [w_i])\)
    • per asset
    • per chain
  • If \(i>=3\) and for each \(i \in I\), \[d_i=w_i\]
  • and also the pair of Depositor and Withdrawal is a only match - then it's likely Depositor address is highly related to Withdrawal address.

Heuristic 2: Same Address Depositing & Withdrawing with Balance Clearing ✅ (implemented)

  • Take each wallet, calculate balance \(b_i\) per block, based on deposits (add balance) and withdrawals (remove balance)
    • per asset
    • per chain
  • Check the pool where wallet's balance \(b_i>0\), for all \(i \in I\)
  • and ending balance \(b_N=0\)

Heuristic 3: Connected Components (using BFS/DFS) Labeling

, based on

  • Token Transfer
  • ETH Transfer
  • NFT Transfer

Heuristic 4: Fixed Active Time Window

Heuristic 5: Fixed Gas Price of Txs Submission

Idenfication Features

Token holding

  • Presale / Investment
  • NFT Communities
    • Bluechip NFT
    • Social NFT
      • ENS ✅ (implemented)

Behavior Set

  • Interaction with DEX
  • Interaction with Lending Protocol
  • Top Token Transfer

Data Set

Input

Tornado Cash Contracts Deposits & Withdrawals:

, across

  • Ethereum (etherscan list)
  • Polygon (not available on Dune V2)
  • BSC
  • Avalanche
  • Arbitrum
  • Optimism
  • Gnosis

We queried from the following 2 Dune v2 Spells tables:

tornado_cash.deposits
tornado_cash.withdraws

ENS Registrant Mapping on Ethereum

we decoded it based on an existing work in v1, and created the following Dune v2 Spells table:
ens.resolver_addresses

*currently not including subdomain

Output

  1. Tornado Records Search Result
Blockchain ENS Pool Deposits Withdraws First Seen Last Seen
string array string int int timestamp timestamp

screenshot:

  1. Heuristic 1: Potential Linked Address based on total amount across pool
Depositor Recipient 0.1ETH 1ETH 10ETH 100ETH
string string int int int int

screenshot:

  1. Heuristic 2: Self Interaction with balance clearing
block_time chain_pot actions
timestamp string int

actions: when positive, meaning depositing into note; when negative, meaning withdrawing from note; number represents the number of actions per block_time

screenshot:

Future Work

  • Host server for the website, add DDOS and API Key protections;
  • Expand with Lens dataset on Polygon, for richer idenfitication;
  • Expand ENS coverage to be subdomains compatible
  • Implement other detection heuristics as described above, to expand the risks alert coverage;
  • Construct the query result into a table (or materialized view) in Dune's backend with cron job, so to improve the API response time

References

Deanonymising the Kucoin Hacker - Koh Wei Jie

Blockchain is Watching You: Profiling and Deanonymizing Ethereum Users
Paper | Github | Vitalik's Tweet

OFAC Sanctioned Contract List

Credits

Mentors: Prestwich@Nomad, Meghan@Dune, Dias@Dune, Shumo@Manta

Advising Wizards: danner.eth, Msilb7.eth

Select a repo