💀Potential Vulnerabilities in EVM Implementations: Overlooked DelegateCall in Precompiled Contracts
Blockchain technology has rapidly evolved over the years, and with it, the desire for improved efficiency and functionality has grown. In pursuit of these goals, several projects have ventured to implement their versions of the Ethereum Virtual Machine (EVM) and introduced custom precompiled contracts to enhance performance. However, while these innovations are commendable, a recurring oversight has emerged, which may pose significant security risks.
Understanding the Basics
Before delving into the potential vulnerabilities, it's crucial to understand the fundamental concepts:
EVM: Ethereum's runtime environment, ensuring consistent smart contract execution across all network nodes.
Precompiled Contracts: These are contracts whose functionality is hard-coded into the blockchain nodes. They're designed to perform specific functions more efficiently than a standard smart contract written in Solidity could. Given their hard-coded nature, they're less flexible than regular contracts but can be much faster and less gas-intensive.
DelegateCall: A unique functionality in Ethereum smart contracts. It allows a contract to execute the code of another contract while preserving its own state. In simple terms, Contract A can "borrow" the logic of Contract B without changing Contract A's data.
The Overlooked DelegateCall
The DelegateCall function has proven to be a double-edged sword. While it can be handy for contract upgrades and logic reuse, it can also introduce vulnerabilities if not appropriately managed. This is especially true for projects that introduce custom precompiled contracts without adequately considering the implications of DelegateCall.
Here's the crux of the issue: When new EVM implementations create custom precompiled contracts, they inherently trust that these contracts are safe since they're hardcoded. But if these precompiled contracts are made accessible via DelegateCall from other contracts, and the EVM implementation hasn't been designed with this in mind, unforeseen behaviors might emerge.
The Off-chain Dilemma
The security concerns don't stop at the blockchain's edge. Many blockchain projects incorporate off-chain systems to improve scalability and efficiency. These systems, designed to work seamlessly with on-chain components, often rely on the predictability and security of the on-chain environment.
If a new EVM implementation's precompiled contracts are not designed to handle DelegateCall properly, malicious actors might exploit this oversight, triggering unpredictable behaviors in the associated off-chain systems. Since off-chain systems don't benefit from the same consensus and immutability mechanisms as on-chain processes, vulnerabilities here can have far-reaching implications.
Extended Example: The Misleading DelegateCall
Let's delve into an illustrative scenario to capture the described vulnerability in the presence of msg.value
and payable
.
Imagine a blockchain ecosystem with two main precompiled contracts - DepositContract
and EventLogContract
.
Typically, users would send ether to the DepositContract
using the acceptEther
function. Based on the msg.value
, the contract then calls EventLogContract
to emit an event specifying the deposited ether amount. Off-chain systems, listening to these events, would then credit users on Layer 2, given the ether has been locked on Layer 1.
However, let's consider the scenario where a malicious smart contract uses DelegateCall to exploit this setup:
Understanding the exploit:
The malicious actor deploys
MaliciousContract
providing the address of theDepositContract
.The actor then invokes the
exploit
function of theMaliciousContract
, sending along some ether.Inside the
exploit
function, a DelegateCall is made toDepositContract's
acceptEther
function. Given it's a DelegateCall, themsg.value
remains the amount sent by the attacker, but the ether is not actually transferred to theDepositContract
.The logic of
acceptEther
is borrowed, and it misleadingly calls theemitDepositEvent
ofEventLogContract
emitting an event thatmsg.value
ether has been deposited.Off-chain systems, which are programmed to credit users based on these events, might be tricked into crediting the malicious user on Layer 2 without any actual deposit on Layer 1.
Outcome: The vulnerability exposes the DelegateCall feature's potential misuse, especially when combined with msg.value
. Custom precompiled contracts and the off-chain systems listening to their events must be designed with a deep understanding and caution against such manipulations.
Last updated