Image from web

On 07/12, 0x announced the existence of a critical vulnerability in the 0x v2.0 Exchange contract which would allow an attacker to fill certain orders with invalid signatures. In less than eight hours, the vulnerable contract was shutdown, patched, and re-deployed. As a result, DEXs and wallets which used 0x protocol also suspended their services, including Radar Relay, Tokenlon, Star Bit etc.

PeckShield researchers thoroughly reviewed the 0x v2.0 Exchange contract and found that the flawed signature verification logic allows an attacker to impersonate a victim maker and make profit from it, for example, making an abnormal order and taking the order by herself.

0x protocol

0x is an open-source protocol which enables point-to-point trading based on Ethereum. It aims to create a standard protocol that allows everyone to run a decentralized exchange. Specifically, in 0x, the orders are matched off-chain and settled on-chain with the help of relayers which provide order services.

0x protocol is adopted by many DEXs and wallets including top-ranked DEXs (by Etherscan): Radar Relay and Tokenlon.


Figure 1: Top-ranked DEXs by Etherscan

As shown in DAppTotal, they are both ranked in top 10 largest DEXs in daily transaction volume.


Figure 2: Top-ranked DEXs in 24h Transaction Volume by DAppTotal

Details

The vulnerability exists in two functions, isValidWalletSignature() and isValidValidatorSignature(). Since these two functions are pretty similar, we will elaborate the details of the vulnerability in isValidWalletSignature().

isValidWalletSignature(bytes32 hash, address walletAddress, bytes signature) is designed to verify if signature matches the result of isValidSignature() defined in walletAddress with corresponding inputs.


Figure 3: The flow of isValidWalletSignature(bytes32,address,bytes)

Specifically, there are two parts in this function:

A) Construct the ABI-encoded data that will be sent to walletAddress.

B) Perform the call to walletAddress and check the return value.

Let’s take a closer look into Part B which is implemented in inline assembly:

  1. Let cdStart point to the start of calldata;

  2. staticcall() into walletAddress to verify the signature. Note that cdStart is used for both input and output.

  3. Check staticcall()’s return value.

During analyzing EVM source code, PeckShield researchers find that if walletAddress is an EOA address (not a smart contract), the function directly returns. In this case, cdStart makes no change after calling staticcall(), leading to isValid check bypassing any non-zero cdStart.


Figure 4: EVM source code

Exploit

In this paragraph, we explain how to exploit this vulnerability. Specifically, a normal user can invoke fillOrder(Order,uint256,bytes) to complete a token trading operation with user-defined parameters.


Figure 5: The flow of fillOrder(Order,uint256,bytes)

The three parameters are:

  1. The order structure;
  2. Token amount that taker fills the order;
  3. Signature of the order.

However, the signature of the order is verified by isValidWalletSignature() as we mentioned earlier. If the signature type is SignatureTypeWallet and walletAddress is an EOA address, the verification can be bypassed. In other words, an attacker can first make a malicious order with the victim’s identification, for example, an extremely low price for selling XYZ tokens. Then she takes this order, gets some XYZ tokens at really low price, and make profit by selling the tokens in other exchanges. As the order is directly sent to the smart contract, the abnormal behaviors can not be identified by relayers.

Consequences

Based on the analysis, users who did authorized transfer on 0x-based exchanges are prone to the following attacks:

The attacker can fake his/her order and get tokens at extremely low price.

After verifying the vulnerability, 0x project used the AssetProxyOwner contract to shut down the v2.0 Exchange and all AssetProxy contracts to prevent this vulnerability from being exploited. Then, they patched and re-deployed the entire 0x smart contract. From our side, PeckShield researchers have analyzed the data on blockchain and confirmed that no asset loss caused by this vulnerability since 0x Exchange contract created.

Conclusion

The vulnerability in 0x v2.0 Exchange contract is mainly caused by the use of inline assembly. Although assembly code can improve execution efficiency and reduce gas consumption, it depends on the understanding of EVM. A wrong usage of assembly code can lead to abnormal operations or security issues.

We suggest developers to audit their smart contracts to avoid similar problems. For Defi projects like DEXs, security is the most important thing. Before deploying the contract, make sure to consult with security firms and conduct for an audit.

About Us

PeckShield Inc. is a leading blockchain security company with the goal of elevating the security, privacy, and usability of current blockchain ecosystem. For any business or media inquiries (including the need for smart contract auditing), please contact us at telegram, twitter, or email.