Back to Blog

#10: ThirdWeb Incident: Incompatibility Between Trusted Modules Exposes Vulnerability

Code AuditingPhalcon Security
February 22, 2024
7 min read
Key Insights
  • Thirdweb disclosed critical flaws (Dec 5, 2023) in prebuilt ERC-20/721/1155 contracts, which were actively exploited after disclosure.

  • Root cause: incompatibility between ERC-2771 meta-transaction context and OpenZeppelin’s MulticallUpgradeable—multicall's delegatecall preserved the forwarder-appended sender, letting callers spoof _msgSender().

On December 5, 2023, the prominent Web3 development platform Thirdweb disclosed significant smart contract security vulnerabilities affecting its pre-built contracts. This critical flaw impacted all ERC-20, ERC-721, and ERC-1155 tokens deployed using these specific vulnerable contracts. In the days following the disclosure, tokens deployed with these vulnerable contracts were progressively exploited in a series of attacks, underscoring the severity of the underlying incompatibility.

Understanding the ThirdWeb Smart Contract Vulnerability

The root cause of the ThirdWeb incident lies in the unexpected interaction between two fundamental components of smart contract development: ERC-2771 and OpenZeppelin's Multicall implementation. To fully grasp the vulnerability, it's essential to understand each component individually and then how their interaction created an exploitable pathway.

ERC-2771: Meta-Transactions and Trusted Forwarders

EIP-2771 defines a contract-level protocol that enables Recipient contracts to accept meta-transactions via trusted Forwarder contracts. This standard is crucial for improving user experience by allowing third parties (forwarders) to pay gas fees on behalf of users, abstracting away the need for users to hold native blockchain tokens.

In practice, OpenZeppelin's ERC2771Context is a widely adopted implementation. Its core functionality involves treating the last 20 bytes of calldata from a trusted forwarder as the effective _msgSender(). For developers using this library, the common practice is to replace all direct uses of msg.sender with _msgSender() to ensure compatibility with meta-transactions. Similarly, _msgData() is used to retrieve the original transaction data, excluding the appended sender information.

function _msgSender() internal view virtual override returns (address) {
    uint256 calldataLength = msg.data.length;
    uint256 contextSuffixLength = _contextSuffixLength();
    if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
        return address(bytes20(msg.data[calldataLength - contextSuffixLength:]));
    } else {
        return super._msgSender();
    }
}

function _msgData() internal view virtual override returns (bytes calldata) {
    uint256 calldataLength = msg.data.length;
    uint256 contextSuffixLength = _contextSuffixLength();
    if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
        return msg.data[:calldataLength - contextSuffixLength];
    } else {
        return super._msgData();
    }
}

Multicall: Batching Transactions for Efficiency

Multicall functionality allows users to bundle multiple function calls into a single transaction, significantly reducing gas costs and improving transaction efficiency. OpenZeppelin's MulticallUpgradeable is a popular implementation for this purpose. It takes an array of calldata bytes and performs a delegatecall for each entry, executing them within the context of the calling contract.

function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {
    results = new bytes[](data.length);
    for (uint256 i = 0; i < data.length; i++) {
        results[i] = _functionDelegateCall(address(this), data[i]);
    }
    return results;
}

(Note: The bug discussed here has since been fixed in later versions of OpenZeppelin's Multicall.)

The Incompatibility: ERC-2771 and Multicall Conflict

The core of the ThirdWeb incident's smart contract vulnerability emerged from a critical inconsistency in how calldata is processed by ERC-2771 and Multicall. ERC-2771 expects the trusted forwarder to pack the message data and sender information together. The recipient contract then uses _msgData() and _msgSender() to correctly unpack this information.

However, the Multicall function, in its vulnerable implementation, was not designed to be compatible with how ERC-2771 packs data for meta-transactions. Specifically, when Multicall processes a batch of calls, it should have correctly extracted the _msgSender() from the initial meta-transaction and then appended this sender information to each individual call's calldata before executing them. This crucial step was missing.

Without the sender information being correctly appended to the calldata within each sub-call processed by Multicall, the ERC-2771 context within the target contract would attempt to unpack sender information from the last 20 bytes of the _msgData() of the sub-call. Crucially, an attacker could control these last 20 bytes. This allowed a malicious actor to craft specific calldata that, when processed by Multicall and then interpreted by an ERC-2771-enabled contract, would execute arbitrary logic with a manipulated _msgSender() value (e.g., an address controlled by the attacker or even a protocol's own pool address). This effectively bypassed the intended security checks and violated the expectations set by both specifications, leading to unauthorized actions.

ThirdWeb Incident: Attack Analysis and Exploitation

Let's examine a real-world example of the ThirdWeb incident's smart contract vulnerability exploitation, using an attack transaction analyzed by BlockSec's Phalcon platform.

The attacker's strategy involved manipulating the _msgSender() to impersonate a Uniswap pool, thereby draining its token balance.

  • Step 1: Initial Token Acquisition. The attacker began by swapping 5 WETH for 3,455,399,346 TIME tokens on a decentralized exchange. This provided the necessary tokens for the subsequent manipulation.

  • Step 2: Malicious Multicall Execution. This is the core of the exploit. The attacker invoked a trusted forwarder with carefully crafted calldata designed to exploit the ERC-2771/Multicall incompatibility. When this calldata was parsed by the Multicall function, it resulted in the burn function of the TIME token contract being called. Crucially, due to the vulnerability, the _msgSender() was incorrectly interpreted as the Uniswap Pool address. This allowed the attacker to effectively burn a significant portion of the TIME tokens held by the Uniswap pool, without actual authorization. The BlockSec Phalcon platform provides detailed transaction tracing to visualize this flow.

    Transaction trace showing the malicious multicall
    Transaction trace showing the malicious multicall

    The image above illustrates how the attacker's Forwarder.execute call is processed. The multicall function receives an array of bytes, which then leads to the burn function being called with the manipulated _msgSender().

    Detailed view of multicall parsing and burn function call
    Detailed view of multicall parsing and burn function call

    This detailed view from Phalcon shows the bytes[] of length 1 being used as data to call the contract, leading to the burn function execution under the false _msgSender().

  • Step 3: Price Manipulation. By burning a large quantity of TIME tokens from the Uniswap pool, the attacker drastically reduced the pool's liquidity for TIME. This artificial scarcity caused the price of TIME relative to WETH to skyrocket within the pool.

  • Step 4: Profitable Arbitrage. With the price of TIME artificially inflated, the attacker then swapped their remaining 3,455,399,346 TIME tokens back for 94 WETH, realizing a substantial profit from the manipulated price.

This sequence of events demonstrates a sophisticated attack leveraging a subtle smart contract vulnerability stemming from module incompatibility.

Secure Your Smart Contracts with BlockSec

Don't let hidden incompatibilities expose your project to risks. Our expert auditors conduct comprehensive smart contract audits to identify and mitigate vulnerabilities before they can be exploited.

Best Security Auditor for Web3

Validate design, code, and business logic before launch

Key Takeaways and Lessons from the ThirdWeb Incident

The ThirdWeb incident serves as a critical reminder of the complexities inherent in Web3 security, particularly concerning the interaction of third-party libraries.

  • Interoperability Risks: In the rapidly evolving DeFi space, projects heavily rely on a stack of third-party libraries and modules. While these components accelerate development, their interactions can introduce unexpected and covert vulnerabilities. The ThirdWeb incident clearly illustrates that even widely-used, seemingly robust components like OpenZeppelin's ERC2771Context and MulticallUpgradeable can create critical security gaps when their integration isn't meticulously handled.
  • Deep Technical Auditing is Essential: This type of smart contract vulnerability is not easily caught by superficial checks. It requires deep technical expertise to analyze how different modules process and interpret data, especially calldata, and identify potential inconsistencies. Thorough smart contract auditing, focusing on cross-module interactions and edge cases, is paramount.
  • Continuous Monitoring and Incident Response: Even with robust audits, new attack vectors can emerge. Continuous blockchain security monitoring, like that provided by BlockSec's Phalcon, is crucial for detecting suspicious activity in real-time and enabling rapid incident response to minimize damage.
  • Beyond Individual Module Security: Developers must think beyond the security of individual components and consider the holistic security posture of their entire smart contract system. How data flows between different modules, how contexts are preserved or altered, and how external calls are handled are all critical considerations.

The ThirdWeb incident underscores the importance of a proactive and comprehensive approach to blockchain security. Relying solely on the reputation of individual libraries is insufficient; the interactions between them must be rigorously scrutinized.

Sign up for the latest updates
~$418M Lost: Bitget, NEAR Intents Exploits | BlockSec Weekly
Security Insights

~$418M Lost: Bitget, NEAR Intents Exploits | BlockSec Weekly

This biweekly security report records eight incidents from September 21 to October 4, 2026, with approximately $418.4M in losses across Ethereum, BNB Chain, Solana, Bitcoin, TRON, XRP Ledger, Zcash, Avalanche, NEAR, and related networks. Detailed analysis covers Bitget's $387.5M third-party security product vulnerability and NEAR Intents' $3.87M refund validation flaw and missing state rollback.

Bitget's $387.5M Off-Chain Breach: Beyond Keys and Contracts
Security Insights

Bitget's $387.5M Off-Chain Breach: Beyond Keys and Contracts

On September 24, 2026, attackers exploited a vulnerability in a third-party security product, obtained internal credentials, and forged withdrawal commands. The resulting transfers moved approximately $387.5M from some of Bitget's operational wallets across Ethereum, other EVM networks, XRP Ledger, Zcash, and TRON; private keys and cold wallets remained intact. This deep dive summarizes the disclosed incident path and fund flow, examines rapid conversion into native assets and the ecosystem recovery response, proposes a systematic defense-in-depth framework for institutions, and explains how authorized blockchain penetration testing can validate cross-layer assumptions.

~$11.3M Lost: Multicall Router, Nostra | BlockSec Weekly
Security Insights

~$11.3M Lost: Multicall Router, Nostra | BlockSec Weekly

This report, covering 2026/09/14 - 2026/09/20, examines two security incidents with approximately $11.3M in combined losses, on Ethereum and Starknet. In the larger one, a multicall router accepted its own address as a dispatch target, so the nested call reached the Gateway module of a Safe wallet carrying the router's own already-authorized identity instead of the external caller's, and roughly 2,900 `aEthrsETH` was routed out of that wallet into an attacker-created Uniswap v4 pool. On Starknet, Nostra's oracle integration required a minimum of only one aggregated source, so when only two of the three configured price sources reached the aggregation, a manipulated thin-pool quote averaged with a normal quote to value `NSTR` at roughly $49.52, supporting approximately $3.5M of borrowing against overvalued collateral.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit

Get Real-Time Protection with Phalcon Security

Audits alone are not enough. Phalcon Security detects attacks in real time and blocks threats mid-flight.

phalcon security