Different topic this time, we are going to dive into crypto and understand its internals while looking at real case of layering and obfuscation
Let's start with understanding the mental model after an attack / fraud has happened, what an attacker needs to do to launder these stolen crypto, as is any exchange nor services will likely converts them to fiat currency and funds would be immedeatly freezed by authorities
- Placement: In crypto is automatic, with fiat currency there is a concrete need to place the stolen cash into the financial system, with crypto after the theft everything is alredy sitting inside a wallet or as unspended UTXO
- Layering: The process of obfuscating and cleaning the origin of those cryptos on the blockhain.
- Integration: where laundered funds re-enter the legitimate economy. At this point, the money appears to come from a legitimate source and can be used freely.
in this research we will see the core and the most "accessible" in terms of research of the 3 stages, the layering
LAYERING // 00
We are going to see some on chain techniques from an analyst prospective and how funds could be traced around services and chain analysis during the obfuscation process
Chain hopping via bridges and DEXs // 01
Briefly, majority of bridges works by a mechanism called Lock-and-mint, you lock N token on a smart contract inside chain A (source) and on chain B (destination) you mint a copy of N token
Cross-chain DEXs(eg: THORChain) on the other hand exchange one token for the other often by utlizing specific liquidity pools
EasyFi founder (Ankitt Gaur) hack
A practical example happenend in April 2021 after Ankitt Gaur personal devices was infected with malware. Interested wallets:
0x437147DA920714feC4822F0666D940945f9c972BLoot wallet0x31499e03303dd75851a1738e88972cd998337403"Easify Hacker"0x83a2EB63B6Cc296529468Afa85DbDe4A469d8B37reutilized wallet across attacks
RenBTC is an ethereum ERC-20 token that rapresent 1:1 with BTC, RenBTC allows lock-and-mint across Ethereum -> Bitcoin and vice versa
The transaction have called Burn() function of RenBTC smart contract, doing a research of 0x83a2e inside the TXs history of that contract
We need TXs with 0x000 as out address and the Burn() method, this is the lock-and-burn implementation
Decoding the LogBurn() _to argument we have 17WFZENdcgkCvVjENQWJnqwXyiCkgTdGbi, the output address in BTC
Based on this its pretty straight forward to trace a hop, no difference if executed by a smart contract function or by using a payload in the transaction if the chain doesnt support smart contracts (BTC). In both case we know that the destination address needs to be passed as argument or somehow to the transaction as input
The real advantage of hopping is not about obfuscation but more about nativeness, services that only exists on a specific chain, in this case ChipMixer on bitcoin
Tumblers/Mixers // 02
Mixers are designed to obscure the correlation betweeen the sender and the recipient address. A user deposits a fixed amount of N cryptoassets, which are pooled with funds from other users. The mixer then either returns an equivalent amount (minus a fee) of different coins to a new wallet address or splits the returned amount across multiple addresses
2023 Coinshift attack
Related addresses:
0x979ec2af1aa190143d294b0bfc7ec35d169d845c0x68c4a151d436ec1c5448d225a97bd19cce4dfed00xbcd5b968a79a04bf2bb942a449f10c20a7121ed8 0xe10d
0x4c7c2b39e3d642d452adfca632939a60b1baacf7
We have 0x68c4 sending 900 ETH to 0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b, a well known address on the ethereum
chain, its a Tornado Cash Router. Routers mantains a list of Tornado Cash pools, they are used to route deposits and withdraw to the correctly
tornado cash pool
At the same time a known theft wallet from the Steadefi hack (0xe10d4a5bd440775226c7e1858f573e379d0aca36) has deposited 624 ETH to the same router, correlating both hacks behind the same individuals.
Total deposited: 1,524 ETH
By this point everything become correlation, looking at the 100 ETH pool of tornado cash we have some deposits there at the same time 900 ETH were moved to the Router. Its logical to think about a 9X100 deposit and a 6X100 deposit, we except to see matching withdraw from the 100 ETH pool
1500 ETH are withdrawen from the 100 ETH pools within 24 hrs from the deposit
The 100 ETH pools is at 0xa160cdab225685da1d56aa342ad8841c3b53f291. We can use advanced filters to filter the exact day in the pool and extract the TXs
Mixers are good for anonimity and laundering purposes but they still need some opsec considerations:
- Withdraw correlation: Even if deposits are rounded numbers, stil better to use different pools for the bulk. Never withdraw in batches
- Timining analysis: Trust the mixer service and keep the funds loked for some time, 24hr is not enough
- Use more withdraw addresses, not only 3 as in the Coinshift attack
PEEL CHAINING // 03
Peel chaining exists because of a fundamental rule within the Bitcoin protocol, UTXOs cannot be splitted, if a UTXO contains 1 BTC and the user only needs 0.3 it must spend the full 1 BTC. The wallet will generate a TX with 2 different destiantions: 0.3 as requested payments, 0.7 are sent back to a newly address controlled by the sender
Colonial Pipeline / DarkSide ransom (May 2021)
A ransom payment of 75 BTC landed in 15JFh88FcE4WL6qeMLgX5VEAFCbRXjc9fr on May 8 2021, the same BTCs
were later sended to 1DToN8Q6y31TGAz75Df729Bnujk6Xg7q5X
On TX 0677781a5079eae8e5cbd5e6d9dcc5c02da45351a3638b85c88e5e3ecdc105a7 11 BTC were sended to bc1qu57hnxf0c65fsdd5kewcsfeag6sljgfhz99zwt and 63 to
bc1qxu83k5qkj8kcqdqqenwzn7khcw4llfykeqwg45
Following the 11 BTC they get deposited in bc1q2sewgrnau4e4gvceh8ykzf8lqxawpluu0k0607 inside a joined TX, following the 63 BTC they were sized by the law enforcement
after been deposited into bc1qq2euq8pw950klpjcawuy4uj39ym43hs6cfsegq
2 months later still from bc1qxu83k5qkj8kcqdqqenwzn7khcw4llfykeqwg45 a 66 BTC transaction is done with a joined TX to bc1q2sewgrnau4e4gvceh8ykzf8lqxawpluu0k0607
The joined transaction is the b0e381d02d966acbcd9224817e3db50b2bc3566e0060db36a6a17ee163152dd7, Inside 0xbc1q2sew now sits 107 BTC
Starting from bc1qvya30xewdeatneqj90ypvzq4kjzgyz8cnvu7rm the peel chaining begins, 1 BTC was sended to 166H4Aqb2UsuyNao95pukLwZUEpXcDufso
while 106.82 was returned as change to bc1qghf0kzn5h3u0lu60s5ueqk9kcxkdnn6dtrtutx
bc1qgh sends 3 BTC to 13FmfYyU7MuuBHdYjTRRnabYqbNLykRzsB and 103.82 as change to bc1qdnxhjf8q70xh0relwaaguvrz77mt5u3lhw0l5j. Going like this until
the full 107 initial BTC are completely fragmented
The core concept of peel chaining is that visually speaking on the public chain we cant determine in reality from a TX which output is the external payment and which the internal change. Investigators to correlate the peeling to a single entity often use one of these see if an address near the end of the chain is inside a joined TX with an address at the beggining, investigator can assume both address are under the same private key
So co-spending still remain one of the major opsec failure
Gravity Bridge exploit - laundering operation // 04
On 29 and 30 May 2026, the Gravity Bridge was exploited for approximately $5.4 million through denom mapping poisoning
Gravity is a bridge between Ethereum and Cosmos-based blockchains, using gravity bridge someone can transfer EVM compatible token from ethereum to cosmos and viceversa. The whole mechanism works using lock-and-mint
Gravity has a smart contract deployed on the Ethereum chain named Gravity.sol, its primary pourpose is to lock ERC20 tokens on ethereum so they can be
minted on Cosmos
Not going into details about Gravity internals but something was wrong with deployERC20()
permissions, attacker were able to mint fake tokens on Osmosis with fabricated denom strings. deployERC20() registers these fake denoms
while validators submitted MsgERC20DeployedClaim acknowledgments.
Theft address: 0x7B582033061b96cC3F9421e73a749ED7C62da1F9 immediatly began swapping stolen stable coins into ETH
After the swaps 0x7b58...da1f9 now contains 2,600 ETH, this sum is then moved into 0x4d3ca32e687e871a58b78AcAc73bE59AC37C7A47 throught multiple TXs
0x4d3ca Is where the laundering magic happens, funds were never transfered in bulk, but always splitted in dozens smaller transactions each of 6-10 ETH
TXs of 6 ETH each went out to KYC exchanges like KuCoin and Binance, for a total of ~24 ETH
Another staging controlled address is 0xC8c71AE4261E55A66D9967F2aC252Be4e669f562, 0x4d3ca sends ~884.03 ETH, most of them subsequently deposited into Tornado Cash 100 ETH pool
The largest portion of the funds were transfered into ChangeNOW exchange service, the 6-10 ETH chunks were first deposited into 76 burner relay wallets and then deposited
into ChangeNOW hot wallet 0xeba88149813bec1cccccfdb0dacefaaa5de94cb1
0xeba88149813bec1cccccfdb0dacefaaa5de94cb1 ChangeNOW hot wallet
Other funds, as today, are still sitting in attackers controlled wallets like 0x8eb3AF1D60469A06DE8Ae2c8d3D1A43923EB0832 and 0x28f061789e26d363bcbb4F6FE7fF04F5a02979da
On 2026-06-04, 11x100 ETH and 8x10 ETH were deposited into tornado cash 100/10 eth pool from 0x4d3ca
Total deposited into tornado cash until now:
- May 31 19:02–19:58
0xc8c74×10 ETH - May 31 23:33–23:38
0xc8c72×100 ETH - Jun 3 03:32–03:38
0xc8c76×100 ETH - Jun 4 23:30–23:43
0x4d3c11×100 ETH - Jun 4 23:44–23:50
0x4d3c8×10 ETH
From here situation get complicated, tracing this size of funds from ChangeNOW and Tornado Cash deposits is hard, we still can monitor the sleeping addressesd and
0xC8c71A
Doing some correlation analysis with Tornado Cash relayers, amounts and time i was able to attempt a retrieve of some wallets that could be linked to the laundering going outside the 100/10 ETH pool
DISCLAIMER! This is purely speculative, i cant say for sure if this is the right laundering path from the Gravity exploit
Of the 2020 ETHs deposited into tornado cash pools my attempted tracing covers: 896.8/1,900 ETHs = 47% 9/19 notes from the 100 ETH pool. 9.96/120 = 8% 1/12 notes from the 10 ETH pool
Followed outside 100 ETH pool:
0xD7E56d5BE167A64F0876F74D627c9Eeb280Bcb9F0x8E81aa13027c1877A0A7c4d85cDd19f6e84C4F980x349aa1549280Cf1906879d88A1Eafadbd240938f0x8b99f266b0CCb9aD47Eda6393EB54346B00165730x77E9Baf924EB96A50516c50b0Ce7dcfAF10dB7470xcF8390D494e2e0265F9CB042ce00EfC4DfDd4cb60x8050011d4f5466dc8A7fcb9c61d92ad5a9ca6BeD0x6136D2E58E320bbF758dB9f39F1c7d33816bfd780xBe65Cb8bB7076f08c8d78Fb875C30260a9f8e70d
From the 10 ETH pool:
0x398a509567cD3517B2F20C7EF6c68aa3cE67851A
Using as example 0x8E81: Withdrawal event: Jun 5 00:50:51 (+1h after the last of the 11×100ETHs deposits ended Jun 4 23:50), relayer: 0x16CB924b5b7ef604139bE95F8762ed817852Db92,
60 seconds after receipt: 59.5 ETH → 0xba3cb449 (CoWSwapEthFlow)
Looking at 0xD7E56: Withdrawal event: Jun 5 01:55, fee 0.4318 → 99.568 ETH (+2h after the deposits into the pool), relayer: 0x16CB(same as 0x8E81) fee 0.4318 → 99.568 ETH internal
Jun 4 17:55 — 8h before the withdrawal: received 2.127 ETH from 0x398a509
This even create a link opportunity, give us a clue about the fact that both 0x398a509(10 ETH out) and 0xD7E56(100 ETH out) are operated by the same folks
Nothing from the ChangeNOW laundering path...
CONCLUSION // 05
My attempt to understand more about on chain evasion and obfuscation, as we have seen at the end, if done properly, attribution is very difficult to perform and become purely speculative
This was just the tip of the iceberg, X/Telegram investigators have tickled something in me and wanted to understand more, unfortunately i still cant see a more useful implication of crypto other than laundering