THORChain Hack
The Story
In July 2021, THORChain, a cross-chain decentralized exchange (DEX), suffered a series of devastating attacks. The first major exploit occurred on July 15, resulting in losses of approximately $8 million. This was quickly followed by a second attack on July 23, which drained an additional $8 million from the protocol.
What made the THORChain situation unique was that after the second attack, the hacker actually left a message claiming they could have stolen more but chose to limit their theft to teach the team a lesson about security. They even offered to return the funds for a 10% bounty, stating they wanted to "teach THORChain a lesson."
The attacks led to a temporary suspension of the network while the THORChain team worked to implement security improvements. The team took the unusual approach of being extremely transparent about the exploits, publishing detailed post-mortems and working in public to fix the vulnerabilities, which earned them praise from the community despite the security failures.
Technical Analysis
The July 15 THORChain hack exploited a vulnerability in the protocol's ETH Router contract, which handles the cross-chain swapping of Ethereum-based assets. The attack was sophisticated and took advantage of how the router processed certain transactions:
- The attacker created a custom contract that mimicked a legitimate router
- When interacting with THORChain, they tricked the protocol into processing their deposit as ETH when it was actually an ERC-20 token
- This confusion in asset type validation allowed them to extract more value than they put in
- The attacker repeated this process multiple times, draining funds from the protocol
The vulnerability existed in how the router contract validated incoming assets:
// Simplified representation of the vulnerable router code
function depositAsset(address asset, uint256 amount) external {
// Vulnerability: Insufficient validation of asset types
if (asset == address(0)) {
// Handle ETH deposit
require(msg.value == amount, "Amount mismatch");
// Process ETH deposit
} else {
// Handle ERC-20 deposit
IERC20(asset).transferFrom(msg.sender, address(this), amount);
// Process ERC-20 deposit
}
// Issue assets on THORChain
_issueTHORChainAssets(asset, amount);
}
The key vulnerability was that the contract didn't properly differentiate between native ETH and wrapped tokens in certain edge cases, allowing the attacker to confuse the system about what type of asset was being deposited.
Lessons Learned
- Cross-chain bridges need rigorous security models with proper asset validation
- External security audits should be standard for any protocol handling significant value
- Rate limiting and circuit breakers should be implemented to limit damage from exploits
- Bug bounty programs can help identify vulnerabilities before they're exploited
- Transparency in security incidents can help maintain community trust even after exploits