Potential Vulnerabilities in EVM Implementations: Overlooked DelegateCall in Precompiled Contracts
Last updated
Last updated
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.
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 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 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.
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 the DepositContract
.
The actor then invokes the exploit
function of the MaliciousContract
, sending along some ether.
Inside the exploit
function, a DelegateCall is made to DepositContract's
acceptEther
function. Given it's a DelegateCall, the msg.value
remains the amount sent by the attacker, but the ether is not actually transferred to the DepositContract
.
The logic of acceptEther
is borrowed, and it misleadingly calls the emitDepositEvent
of EventLogContract
emitting an event that msg.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.
,