Our Analysis of the $80M Qubit Finance Exploit
According to our SlowMist Intelligence, on January 28, 2022, Qubit Finance experienced a loss of around $80 million as a result of an exploit. We’ve conducted an investigation into this event, and the following are our findings.
1. The attacker first deposits funds into the QBridge contract on the Ethereum blockchain. Then creating a contract that allows the target chain destinationDomainID to be crossed and the asset resourceID to be cross-chained. It is composed of the cross-chain funds and the receiving address.
2. The attacker specifies that the incoming resourceID is the required value for cross-ETH tokens, but calls the QBridge deposit function rather than the depositETH function. As a result, the check between the amount of cross-chain funds and the msg.value is bypassed.
The deposit function extracts the original address from the mapping based on resourceID called. It can be successfully called because the attacker is able to pass in the value required for the real cross-ETH token.
3. The handler contract’s deposit function determines whether the token obtained by the resourceID is in the whitelist. Since the resourceID passed in by the attacker corresponds to the ETH, and the tokenAddress is 0, it passes the whitelist check. However, the tokenAddress to be called is not checked again in the deposit function (the called ETH should be cross-chained via the depositETH function), and the token’s transferFrom function is called directly by safeTransferFrom.
4. Because the token address to be used is 0 address, and when it calls an EOA address without code size, the execution result is true and the return value is empty. This transfer operation of transferFrom passes the check of safeTransferFrom, and finally triggers the Deposit cross-chain function.
5. Once the receiving resourceID meets the required value, the Deposit function is invoked, which ultimately recharges the ETH. This causes the QBridge contract to believe the attacker has made ETH cross-chain deposits, leading to a massive quantity of qXETH tokens being minted on the BSC chain for the attacker.
The attacker then utilized this qXETH as collateral in order to obtain a loan from the Qubit loan pool.
The main reason for this exploit is that under the condition that the recharge of the ordinary token and the native token are carried out independently. When the token in the whitelist is transferred, it is not checked again whether it is the 0 address. This results in the operation that should have been recharged through the native recharge function to smoothly pass the ordinary token recharge function. The SlowMist security team recommends that after checking the whitelist of deposit tokens, it still needs to be checked whether the deposited tokens are native tokens.