According to THORChain’s treasury report for Q1 2022 released on April 1, the chain registered a growth in revenue despite the twofold impact of persistent market sluggishness and highly unstable geopolitical factors. Public data shows that THORChain recorded $2.17 billion in revenue in Q1 2022. THORChain, acclaimed as the “cross-chain version of UniSwap”, gained a foothold in the cross-chain trading market relying on its unique advantages and earned extensive recognition among investors.
Behind all these glamours, THORChain is also deeply troubled by hacking. The chain suffered frequent security breaches since it was launched on Ethereum, a fact that casts doubt on its security. On April 11, THORChain tweeted about phishing attacks, warning users not to interact with [DeTHOR] or other unknown tokens within their wallets, which once again raised concerns about its security issues.
While building a sound security system for CoinEx products, the CoinEx security team also keeps track of security incidents in the blockchain space to help users better understand the security of different projects from the perspective of technical security and mitigate the investment risk. Aiming to improve the security criteria for the blockchain sector, the CoinEx security team has analyzed the security risks of THORChain (RUNE). The team hopes that THORChain could note and mitigate the following risks by optimizing the relevant smart contract codes. In addition, this article is also a warning for users, reminding them to be more aware of asset security and avoid asset losses.
How secure is THORChain (RUNE)?
Through analysis of the contract code and logic of THORChain (RUNE), the CoinEx security team has found the following risks:
To begin with, let’s check out the contract code of THORChain (RUNE):
We can tell that RUNE is a pretty standard ERC-20 token. It should be noted that apart from the ERC-20 interface, THORChain (RUNE) offers an additional interface:
According to transferTo (as shown in the picture above), THORChain (RUNE) uses tx.origin, which is one of the causes behind its security risks. Here, we should explain the difference between tx.origin and msg.sender:
The below picture describes what happens when a regular address calls the smart contract:
In such cases, msg.sender = account.address, and tx.origin = account.address, which means that msg.sender is just the same as tx.origin.
The following is what happens when an account calls contract A, and contract A calls contract B:
When contract A calls contract B (as shown above), we can tell that msg.sender equals tx.origin in contract A.
However, in contract B, msg.sender = contractA.address, while tx.origin = account.address. Therefore, tx.origin is like a global variable that traverses the entire call stack and returns the address of the account that originally sent the transaction. This is the key issue: to date, almost all known attacks against THORChain (RUNE) relate to tx.origin.
Let’s now find out how attackers steal users’ RUNE tokens through tx.origin:
Attack No.1: Pilfer a Goat from a Herd
Addresses on Ethereum are divided into external addresses and contract addresses. Transferring ETH to these two types of addresses through external addresses is fundamentally different. The Official Documentation of solidity states that a contract address must implement a receive Ether function before making transfers.
In light of the features of tx.origin, hackers may build an Attack contract:
When the Attack contract receives an ETH transfer from a user, it will “pilfer a goat from a herd” — the contract will steal the user’s RUNE tokens in the process.
Attack No.2: Internal Attack
An Internal Attack is a special type of attack. When trying to steal a user’s RUNE through an Internal Attack, the hacker needs to have a medium token. Moreover, the token must also call third-party contracts. According to the transfer records of RUNE on Ethereum, some attackers hacked RUNE through AMP Token transfers.
AMP Token uses the ERC-1820 standard to manage Hook registration and examine whether Hook is registered upon each transfer. If Hook has been registered, then the Hook will be called.
The contract code of AMP Token shows that the final implementation of the transfer is: _transferByPartition. Meanwhile, there are two calls involving transferHook: _callPreTransferHooks (before the transfer) and _callPostTransferHooks (after the transfer). In particular, _callPreTransferHooks is for the from address, while _callPostTransferHooks is for the to address (i.e. the receiving address).
For regular users, stealing tokens from themselves is pointless. Therefore, attackers may exploit _callPostTransferHooks. Let’s now check out the codes of _callPostTransferHooks.
We can tell that the only callback that attackers could exploit is IAmpTokensRecipient(recipientImplementation).tokensReceived()
Next, we will illustrate how this call can be used to transfer a user’s RUNE while making an AMP Token transfer.
Step 1: A call contract is needed (as shown below):
Step 2: Deploy the contract to obtain the Attack Address.
Step 3: Call the ERC-1820 contract interface (setInterfaceImplementer) to register the interface.
ERC-1820 Address: 0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24
Contract interface: setInterfaceImplementer(address toAddr, bytes32 interfaceHash, address implementer)
In particular, toAddr is the receiving address of the AMP transfer,
interfaceHash is the hash of AmpTokensRecipient:
Implementer is the Attack Address obtained in Step 2.
Step 4: Lure a user to transfer AMP to the toAddr to trigger a callback, and steal his RUNE at the same time.
Attack No.3: Phishing Attack
As its name suggests, in a phishing attack, the attacker promises to give away incredible benefits to lure users into performing certain contract operations. Here, we will introduce a common phishing attack.
Step 1: The attacker issues an ERC-20 token, and may write it into any contract interface that involves signatures.
Step 2: Create a trading pair on Uniswap or any other swap;
Step 3: Offer airdrops to all users/addresses who hold RUNE tokens;
The initial work of the phishing attack is basically completed through the above these steps. Next, the attacker only has to wait for users to trade on a swap, and users risk losing their RUNE once they perform operations such as approve, transfer, etc.
In addition, in order to further verify the security risk of THORChain contract code, CoinEx has discussed with the security team from SlowMist and PeckShield, two well-known security agencies in the industry. Confirmed by SlowMist and PeckShield, the security risk mentioned above does exist.
So far, we have covered several types of attacks, as well as the security risks that users are exposed to.
How should the project team optimize the contract code to make itself more secure and protect users’ assets?
The only answer is to be cautious about using tx.origin.
How can regular users mitigate risks and protect their assets in the face of attacks that seem unavoidable? The CoinEx security team offers the following suggestions:
For Attack No.1: When making a transfer, keep track of the estimated Gas consumption. For a regular ETH transfer, a Gas fee of 21,000 is more than enough. Be careful if the Gas consumption far exceeds that figure.
For Attack No.2: Isolate your tokens by adopting different wallets. You can store different tokens in different addresses. Extra caution is needed when it comes to the hot wallet address offered by exchanges.
For Attack No.3: Greed is the source of all evil. Do not blindly participate in any airdrop event.
Security has always been a top concern in the blockchain sector. All players, including project teams and exchanges, should prioritize security during project operation, keep users’ assets safe and secure, and jointly promote the sound growth of the blockchain industry.