The Further Analysis of the Poly Network Attack

  • The Ontology relayer does not have enough validation mechanisms for the transaction from the Ontology chain.
  • The attacker can directly invoke the putCurEpochConPubKeyBytes function in EthCrossChainData without going through the Ethereum relayer, as long as there is a valid block on the Poly chain.
  • The hash collision as pointed out by Kevin (

0x.1 Transactions and Contracts

Attack Flow

Ontology transaction -> Ontology relayer -> Poly chain -> Ethereum relayer -> Ethereum
0x838bf9e95cb12dd76a54c9f9d2e3082eaf928270: EthCrossChainManager 0xcf2afe102057ba5c16f899271045a0a37fcb10f2: EthCrossChainData 0x250e76987d838a75310c34bf422ea9f1ac4cc906: LockProxy 
Transaction: 0xb1f70464bd95b774c6ce60fc706eb5f9e35cb5f06e6cfe7c17dcda46ffd59581
Transaction: 0xf771ba610625d5a37b67d30bf2f8829703540c86ad76542802567caaffff280c
Transaction: 0x1a72a0cf65e4c08bb8aab2c20da0085d7aee3dc69369651e2e08eb798497cc80

0x2. Attack Flow

Take the attack occurred on Ethereum as an example. This is a cross-chain attack involving three chains (and their corresponding relayers), i.e., Ontology Chain, Poly Chain and Ethereum.

  1. the attacker first initiated a malicious transaction (0xf771ba610625d5a37b67d30bf2f8829703540c86ad76542802567caaffff280c) on Ontology Chain;
  2. the attacker then modified keeper’s public key stored in the EthCrossChainData contract on Ethereum;
  3. the attacker finally crafted a malicious transaction to harvest crypto assets.

0x2.1 The First Step

The attacker first initiated a cross-chain transaction (0xf771ba610625d5a37b67d30bf2f8829703540c86ad76542802567caaffff280c) from Ontology, which includes a malicious payload:

0x2.2 The Second Step

The attacker manually sent transaction to Ethereum by invoking the verifyHeaderAndExecuteTx function of the EthCrossChainManager contract. The malicious transaction data stored on Poly Chain was used as the input. As a valid Poly Chain transaction, it was able to bypass the verification (including the signatures and the merkle proof) in the verifyHeaderAndExecuteTx function. After that, the putCurEpochConPubKeyBytes function of the EthCrossChainData contract was invoked to modify the original four keepers to a new one (i.e., 0xA87fB85A93Ca072Cd4e5F0D4f178Bc831Df8a00B) controlled by the attacker.

0x2.3 The Third Step

After the modification of the keeper, the attacker was able to directly call the verifyHeaderAndExecuteTx function without using Poly Chain. Finally, the unlock function of the LockProxy contract was invoked to stole huge amount of digital assets from Ethereum. The detailed analysis can be found in our previous report [1].

0x3. Relayer

Both Ontology and Ethereum relayers are implemented in Go. However, they lack of enough validation so that

  • The attacker can construct a malicious transaction, which will be packed into the Poly chain
  • The attacker can directly invoke the functions in the EthCrossChainData smart contract on Ethereum

0x3.1 Ontology relayer blindly trusts the cross-chain transactions from Ontology

The ont_relayer( is responsible for listening to cross-chain transactions from the Ontology chain and sending them to the Poly chain.

  • Side means the Ontology chain; Alliance means the Poly chain
  • CrossChainContractAddress is the native smart contract (number 09) on the Ontology chain

0x3.2 Bypass Ethereum Relayer

Ethereum Relayer is responsible for listening transactions from the Poly chain and then sending the transaction to Ethereum.


Yufeng Hu, Siwei Wu, Lei Wu, Yajin Zhou @ BlockSec



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


The BlockSec Team focuses on the security of the blockchain ecosystem and the research of crypto hack monitoring and blocking, smart contract auditing.