# Unsafe External Calls and Their Vulnerabilities

In smart contract development, especially in decentralized finance (DeFi) and cross-chain protocols, making external calls is often necessary. However, **unsafe external calls**—especially those made to user-controlled addresses or with unvalidated calldata—can open the door to some of the largest exploits ever seen in the blockchain space. One of the most notable examples is the **Poly Network hack** of August 2021, where $611 million was drained due to a vulnerability involving an unsafe external call.

In this section, we will explore the mechanics behind unsafe external calls, the risks they pose, and how to implement secure practices to prevent similar vulnerabilities in your smart contracts.

***

#### Understanding Unsafe External Calls

An **external call** occurs when a smart contract interacts with another contract or an external address. External calls are fundamental to blockchain protocols, but they come with risks, especially when a contract makes an external call without verifying the recipient address or ensuring the calldata is safe.

The danger lies in the fact that once a contract makes an external call, it loses control over execution flow, especially if the recipient is a malicious contract. Attackers can exploit this lack of control to re-enter the calling contract, modify state variables, or execute unintended logic.

***

#### How the Poly Network Hack Happened

The **Poly Network hack** is a prime example of how **unsafe external calls** can lead to devastating results. Poly Network, a cross-chain protocol that connected 35 different blockchains, was hacked for $611 million through a vulnerability in its **EthCrossChainManager** contract.

**Vulnerability Breakdown:**

* The **EthCrossChainManager** was a privileged contract responsible for verifying cross-chain transactions.
* It contained a function called `verifyHeaderAndExecuteTx` that validated transactions and then called another internal function: **\_executeCrossChainTx**.
* **\_executeCrossChainTx** made an external call to a variable **\_toContract**, which was **user-controlled**—any user could pass in the contract address they wanted.
* No validation checks were implemented to ensure that the external call was being made to a legitimate or trusted contract.
* Additionally, **\_toContract** accepted a custom **\_method** variable (user-controlled calldata) that allowed users to execute arbitrary logic on the external contract.

The vulnerability came from the fact that **any user** could manipulate the **\_toContract** and **\_method** variables to force the privileged **EthCrossChainManager** to make external calls to **any contract** with **any calldata**.

**Attack Flow:**

1. **Arbitrary Contract Call**: The attacker passed in a malicious contract address to **\_toContract**, and in the **\_method** variable, they brute-forced the correct calldata that would allow them to bypass security checks and execute privileged functions in the target contract.
2. **Privileged Contract Exploitation**: The attacker tricked the **EthCrossChainManager** into calling another Poly Network contract—**EthCrossChainData**. By passing in malicious calldata, they successfully called the function **putCurEpochConPubKeyBytes**, which allowed them to drain funds.
3. **Complete Fund Drain**: Once the attacker gained control of this function, they were able to manipulate the contract and drain over $600 million worth of assets.

***

#### Why External Calls Are Dangerous

1. **Loss of Control**: When a contract makes an external call, control of execution flow is handed over to the external contract. If the recipient contract is malicious or poorly designed, it can manipulate the calling contract’s state.
2. **Reentrancy Attacks**: Unchecked external calls can lead to **reentrancy attacks**, where the recipient contract re-enters the calling contract and executes code multiple times before the original call is finished.
3. **Custom Calldata Exploits**: As in the Poly Network example, allowing user-controlled calldata without validation can lead to attackers executing arbitrary functions, bypassing security checks.

***

#### Best Practices to Mitigate Unsafe External Call Vulnerabilities

To avoid falling victim to vulnerabilities like those seen in the Poly Network hack, it is essential to follow best practices when making external calls in smart contracts.

**1. Validate External Contract Addresses**

Always ensure that external calls are only made to trusted and validated contract addresses. Avoid accepting user-controlled contract addresses unless absolutely necessary.

**Use SafeERC20 for Token Transfers**

If transferring tokens during an external call, use safe transfer methods such as OpenZeppelin’s **SafeERC20** to ensure that the target contract is properly verified and the transfer executes correctly.

**Limit User-Provided Data**

Be cautious when accepting user-controlled calldata or function selectors. If you must allow custom data, validate that the calldata aligns with the contract’s intended functionality.

**Use Reentrancy Guards**

Protect your contract’s functions with a **reentrancy guard** to ensure that external calls cannot re-enter your contract and modify state unexpectedly.

**Check Return Values**

Always check the return values of external calls to ensure that the call was successful and executed as expected. If the call fails or returns false, revert the transaction.
