👓Real World Examples

Understanding the Examples: In the "Examples" section, we plunge into genuine instances of precompiled contract vulnerabilities that have been extracted from real-world incident reports, blockchain security postmortems, and thorough code analyses. Through the examination of these real-life scenarios, you will attain a profound and tangible grasp of the nuances and implications of delegate calls and their potential misuse, especially with precompiled contracts. This understanding will significantly sharpen your audit capabilities and heighten your awareness of the intricacies involved, positioning you to better safeguard blockchain systems against such pitfalls.

Example 1: Exploiting Precompiled Logging Contracts in a Bridge Mechanism

Funds at risk: Direct loss of 70k ETH and $200m in other assets

Bug Bounty Payout: $6m

Blockchain bridges are designed to easily move assets between different chains. A platform we'll refer to as "Aurora" developed a unique system using special contracts for this purpose. In Aurora's system, two main contracts, ExitToNear and ExitToEthereum, were in charge of managing withdrawals.

How the System Was Supposed to Work:

  1. Moving ETH: Users send ETH to a designated contract.

  2. This contract then creates a record, known as the ExitToNear event, which notes details like who sent the ETH, where it's going, and how much is being sent.

  3. After recording this, an exit_event_log with all the event details is produced.

  4. After everything is done, Aurora checks all these logs to confirm the transactions.

The system expects these logs to be made only by a specific address, ExitTo(Near|Ethereum)::ADDRESS.

The Vulnerability:

A close look at the system revealed a weakness. As long as the built-in contracts' codes were activated, these logs could be made. The system only checked if the log was made by the right address, assuming that if msg.value > 0, it meant real ETH was sent.

This is where delegatecall() comes in. If a smart person uses delegatecall() to activate the built-in contract's code, the msg.value from the original call is used, but no real ETH is moved.

The Sneaky Contract:

A tricky person could use a contract like this:

pragma solidity ^0.8.0;

contract TrickyContract {
    function pullAFastOne() public payable {
        bytes memory input; // The needed input for the delegate call
        uint input_size;    // The size of the input
        // Making the delegatecall to the bridge contract
        (bool success, ) = address(0xe9217bc70b7ed1f598ddd3199e80b093fa71124f).delegatecall(
            abi.encodeWithSelector(bytes4(keccak256("functionInBridgeContract(bytes)")), input)
        );
        require(success, "Delegate call didn't work");
    }
}

The critical thing here is that when the tricky contract uses delegatecall on the bridge contract, the bridge contract then calls the event emitter contract, giving false information.

How the Trick Works:

  1. The tricky person moves Ether from Ethereum to Aurora.

  2. They then use the sneaky contract on Aurora.

  3. When they activate the sneaky contract, Aurora is fooled into thinking that ETH was sent, and sends out the equivalent in another currency (let's say nETH) on another platform (like NEAR). But the tricky person's balance on Aurora doesn't decrease.

  4. They can then send the nETH back to Aurora and get double the amount they originally had.

  5. This can be done again and again for more profit.

Mitigation:

To address the vulnerability, Aurora implemented a fix where an exit error is produced if the provided address doesn't align with the inputs' address. This action effectively deactivates the option to use DELEGATECALL in a manner akin to the previous disabling of STATICCALL. Additionally, Aurora instituted a test designed to monitor and ensure that any future changes in logic won't reintroduce this vulnerability. The bug fix was only later published in the Aurora Engine release 2.5.3. You can also check the change log and the diff.

Conclusion:

This example shows how important it is to understand how Ethereum's functions work when designing complicated systems. It also highlights the need for thorough checks and testing, especially when building bridge mechanisms. Using special contracts can be risky, so it's important to be careful and know what might go wrong.

Example 2: Exploiting Velas' VLX Bridging Mechanism

Funds at risk: The infinite inflation of VLX could have destroyed Velas’ $100M market cap

Bug Bounty Payout: $100k

Introduction:

Velas is a blockchain system that supports Ethereum Virtual Machine (EVM) transaction execution. This is done by wrapping EVM transactions into native Solana-like transactions and instructing a specific EVM Program to execute the EVM transaction within the chain's built-in EVM.

Currency Management in Velas:

On the Velas chain, the native currency is called VLX. VLX can exist in two spaces:

  1. Native Space (Solana Space): Where VLX is owned by a native, Solana-type account.

  2. EVM Space: Here, VLX belongs to an EVM address. In the Native space, this VLX is seen as being under the custody of the EvmState account.

VLX Bridging:

To move VLX from the EVM space back to the Native space, users would send a transaction to a predefined contract named ETH_TO_VLX at the address 0x56454c41532D434841494e000000000053574150. This contract had a simple interface:

interface ETH_TO_VLX {
    function transferToNative(bytes32 native_recipient) external payable;
}

The Vulnerability:

The problem with the ETH_TO_VLX contract is eerily similar to the Aurora case. The contract didn't consider the possibility of being invoked via a delegatecall. Therefore, it didn't accurately check if funds intended for bridging were genuinely sent to it.

In a proof of concept for this vulnerability, a malicious actor could design a contract that uses delegatecall to communicate with the ETH_TO_VLX contract. By doing this, it's possible to dupe the contract into thinking that VLX tokens have been sent for bridging when, in reality, they haven't. The contract is then fooled into moving the equivalent VLX to the attacker's Native space account.

The consequences of this exploit can be catastrophic:

  1. The EVMSTATE Native account's VLX balance can be completely drained.

  2. An infinite amount of VLX tokens can be produced within the EVM space.

Given the potential for infinite VLX minting, the whole Velas ecosystem could be in jeopardy. Especially concerning was the fact that VLX's market capitalization was around 100 million dollars at the time this vulnerability was discovered.

Conclusion:

The Velas case is another testament to the intricate complexities and potential pitfalls in bridging mechanisms between native and EVM spaces. It reiterates the need for thorough validation and checks, especially when constructing bridge contracts. These vulnerabilities, if unchecked, can jeopardize not just a project but the entirety of an ecosystem.

Example 3: Moonbeam Network Vulnerability

Funds at risk: $112M+

Bug Bounty Payout: $1M

Summary: Moonbeam and Moonriver, both EVM-compatible platforms, possess precompiled contracts shared between them. A critical design flaw exists within the implementation of these contracts, potentially jeopardizing more than $100 million worth of assets across DeFi projects.

Details:

  1. Misuse of Delegatecall with Native Contracts:

    • Native contracts are typically prebuilt contracts which provide special functions extending the original EVM.

    • Using delegatecall on native contracts can execute unintended functions. Given that the actual user of these functions can be masked, malicious contracts can impersonate their caller to operate on native contracts.

  2. Vulnerable Precompiled Contracts:

    • The Balance ERC-20 precompile provides an interface to handle native tokens (e.g., MOVR & GLMR) but has a flaw that allows malicious contracts to pass its msg.sender to the precompile contract, enabling unauthorized fund transfers.

    • Similar issues are present in the Asset ERC-20 precompile, which provides an implementation for interoperable tokens. While the design considered the use of delegatecall, the logic failed to operate correctly.

  3. Exploitation Strategy:

    • Airdropping a malicious token to users is one method, where users are tricked into invoking the malicious contract, leading to unauthorized token transfers.

    • More prominently, certain flash loan providers (such as SolarBeam on MoonRiver and StellaSwap on Moonbeam) that support callbacks to arbitrary contracts can be made to unwittingly approve unauthorized transfers, effectively clearing out their liquidity.

  4. Potential Impact:

    • A successful exploitation could lead to a massive drain of funds from various DeFi protocols, with some of the most notable contracts holding assets upwards of $12.6 million.

  5. Native Token Exploitation:

    • The Balance ERC-20 precompile is also vulnerable, allowing attackers to potentially steal native tokens (e.g., MOVR or GLMR) from any user who interacts with a malicious contract. While the exploitation of this flaw isn't widespread, it poses a significant threat when considered in conjunction with lending protocols such as MGlimmer from the Moonwell project. Using the exploit in tandem with repeated borrowing and transfer actions can lead to the draining of all borrowable assets.

Conclusion:

If exploited, this flaw could rank among the most significant heists in DeFi history, with potential thefts totaling over $112 million. Given that the inherent issue lies in the foundational layer of the blockchain system, mitigation is complex and challenging. Immediate and coordinated action is imperative to safeguard the assets and integrity of the Moonbeam ecosystem.

Any questions on the material so far? Ask Omar Inuwa:

LinkedIn, Twitter

Last updated