Analysis of the principle of the ERC2771 and Multicall arbitrary address deception vulnerability

Exploring the Principles of ERC2771 A Critical Analysis of the Multicall Arbitrary Address Deception Vulnerability

On December 8, 2023, OpenZeppelin officially issued an important security alert to the community. The alert pointed out that there is a risk of arbitrary address deception attacks when integrating projects using the ERC-2771 standard and the Multicall approach.

SharkTeam conducted a technical analysis of this incident promptly and summarized security measures, hoping that future projects can learn from it and strengthen the security defenses of the blockchain industry.

1. Attack Transaction Analysis:
Due to a series of attack transactions related to this vulnerability, we chose one of the attack transactions for analysis.

Attacker’s address: 0xFDe0d1575Ed8E06FBf36256bcdfA1F359281455A
Attack transaction: 0xecdd111a60debfadc6533de30fb7f55dc5ceed01dfadd30e4a7ebdb416d2f6b6

Attack process:
1. First, the attacker (0xFDe0d157) exchanged about 3,455,399,346 TIME tokens using 5 WETH tokens.

2. Then, the attacker (0xFDe0d157) constructed malicious calldata parameters and called the [Forwarder].execute function.

3. When calling the [Forwarder].execute function, the malicious calldata triggered the multicall function of the TIME contract. Then, the remaining calldata was used to trigger the burn function of the TIME contract, destroying the TIME tokens in the pool.

2. Vulnerability Analysis:
First of all, this attack event mainly involves several aspects: ERC2771, Multicall, and carefully constructed calldata. We can find the relevant inheritance in the TIME token contract.

1. ERC2771 provides the ability to have a virtual msg.sender, allowing users to delegate a third-party [Forwarder] to execute transactions to reduce gas costs. When submitting a transaction, the msg.sender address will be added to the calldata.

2. The TIME token contract inherits ERC2771Context. When the [Forwarder] calls the contract, _msgSender() checks the calldata and right-shifts it, truncating the last 20 bytes as the expected msg.sender.

3. Multicall is a method of transforming a single function call into calling multiple functions in sequence within the same contract. It accepts an array of user-encoded calls and executes them within the contract itself. This function iterates over the call array and performs delegatecall() for each operation. This allows users to combine their own series of operations and execute them sequentially in the same transaction without predefining certain operation combinations in the protocol. Its main purpose is also to save gas.

4. For carefully constructed calldata, the attacker called the [Forwarder].execute function and passed the relevant parameters.

We obtain the following readable format for the data value:

The attacker (0xFDe0d157) obtained a new data value by manipulating the current calldata offset, and passed this value to the multicall(bytes[]) function. The first 4 bytes of the new data value represent the selector for the burn(uint256) function, with the amount parameter being 62227259510000000000000000000.

5. In the multicall(bytes[]) function, the burn(uint256) function is called using delegatecall. At line 0x20, the address 0x760dc1e043d99394a10605b2fa08f123d60faf84 was appended at the end when constructing the calldata. This address corresponds to the TIME-ETH liquidity pool on Uniswapv2, which was mentioned earlier as the expected msg.sender.

6. Why did the msg.sender become the TIME-ETH liquidity pool address? The reason is that initially, msg.sender was the [Forwarder] contract address. To verify if it is a trusted [Forwarder], if it is trusted, msg.sender is set as the last 20 bytes of calldata.

III. Security Recommendations

The main reason behind this attack: in ERC-2771, the [Forwarder] was not specifically designed for multicall. The attacker added the relevant parameters from the _msgSender() function to the external call of multicall, i.e., the [Forwarder].execute function in this case. Within the multicall function, some functions also append the relevant parameters from _msgSender(), allowing the attacker to deceive the _msgSender(). Therefore, by using multicall to call relevant functions, the attacker can impersonate any address’s call. Ultimately, the attacker gained authorization to burn TIME tokens in the pool.

To mitigate and prevent such incidents, the following measures can be adopted:

1. Use the updated version after fixing the bug. The new version of Multicall from OpenZeppelin includes the context suffix length of ERC2771context data, which is used to identify the expected context suffix length of ERC-2771. Therefore, any calls from trusted [Forwarder] will be recognized and adapted for each sub-function call.

Below is a comparison between the buggy version and the updated version:

2. Prohibit any contract from calling multicall to prevent [Forwarder] from using it. Taking ThirdWeb as an example, this method is different from the solution provided by OpenZeppelin. OpenZeppelin still allows multicall through contracts. Below is a comparison between the buggy version and the updated version of ThirdWeb:

We will continue to update Blocking; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Bitcoin

Vulnerability Discovered in Bitcoin Lightning Network: An Electric Shock to the System

Bitcoin technologist Antoine Riard has uncovered a potentially significant security concern within the Bitcoin Lightn...

Blockchain

Uniswap: Now on Android, Swapping Like a Master

Uniswap caters to the growing demand from Android users by launching a customized crypto wallet for their devices.

Market

🚀 BlackRock’s Bitcoin ETF Sees Unprecedented Trading Volume 🚀

BlackRock's IBIT had an impressive performance as it achieved its second consecutive day of record-breaking trading v...

Market

Raoul Pal owns less than 2% of the cryptocurrency DogecoinGirlfriendHat (WIF) despite a 43% increase in the market.

Raoul Pal revealed that he possesses less than 2% of the popular memecoin dogwifhat (WIF), causing a surge in market ...

Web3

Web3 Investment Sees Major Capital Influx

Great news! GBA Capital Fund is proud to introduce a massive $10 billion investment fund specifically targeted toward...

Market

Grayscale and FTSE Russell Unleash the Cryptocurrency Sector Index Series A Match Made in Blockchain Heaven

UK-based Grayscale, known for their fashion-forward digital investments, is teaming up with FTSE Russell, a division ...