All vulnerabilities
CRITICALWeb3exploited in the wild

WEB3-QUBIT-2022

Web3 · BNB Chain · Qubit Finance (QBridge)

Summary

On 27 January 2022 the Qubit Finance QBridge, connecting Ethereum and BNB Smart Chain, was exploited for about $80 million (roughly 206,809 BNB). The bug lived in a deprecated deposit() function on the Ethereum-side QBridge that remained active after a newer depositETH() path was introduced for native ETH. The legacy deposit() expected an ERC-20 token address but did not validate it against address(0); it called tokenAddress.safeTransferFrom(depositor, address(this), amount) using SafeERC20, and because address(0) has no code the low-level call to a non-contract address returned success without reverting, so safeTransferFrom silently passed while transferring nothing. The function then emitted a Deposit event as if real ETH had arrived. The BSC-side relayer trusted that event and minted qXETH collateral (the attacker obtained around 77,162 qXETH), which the attacker pledged as collateral to borrow out the bridge's deposited assets and convert them to BNB, all without ever locking real value.

How to avoid it in your code

  • Validate that user-supplied token addresses are not address(0) and are on an allowlist before any transfer or credit
  • Require that low-level/SafeERC20 transfer targets contain code (extcodesize > 0); a call to a codeless address returns success
  • Remove deprecated functions outright when migrating; never leave a legacy deposit path callable alongside its replacement
  • Separate native-asset and ERC-20 deposit logic so native value is checked via msg.value, not a token transfer
  • Have bridge relayers verify the actual on-chain balance delta, not just the emitted Deposit event, before minting

References

Related vulnerabilities

All Web3 →