#37593 [BC-Insight] Inconsistent Address Collision Check Against Precompile Contracts During Contract Deployment

Submitted on Dec 10th 2024 at 04:35:52 UTC by @CertiK for Attackathon | Ethereum Protocol

  • Report ID: #37593

  • Report Type: Blockchain/DLT

  • Report severity: Insight

  • Target: https://github.com/paradigmxyz/reth

  • Impacts:

    • (Specifications) A bug in specifications with no direct impact on client implementations

Description

Brief/Intro

Within the contract deployment in the Revm (utilized in Ethereum execution client, Reth), it has the check that the newly created contract address does not belong to the precompile contract addresses, while the Ethereum execution specs and other Ethereum execution clients do not have such check. Though it is unlikely to happen due to the hardness of hash collision, it could lead to consensus issues once it’s triggered.

Vulnerability Details

Affected Codebase: https://github.com/bluealloy/revm/tree/v50

The function make_create_frame() is utilized to create a contract via contract deployment transaction, opcode Create and Create2.

https://github.com/bluealloy/revm/blob/v50/crates/revm/src/context/evm_context.rs#L267

After the address is created via create or create2, it checks if the resulting address belongs to the precompile contract addresses or not:

https://github.com/bluealloy/revm/blob/v50/crates/revm/src/context/evm_context.rs#L320

Though the precompile contract addresses are supposed to be reserved only for the precompile contract, and it indeed should have one. However, this check does not align with Ethereum execution specs and other Ethereum execution clients (We reported it to the Go Ethereum team but they refused to fix it as it aligns with the Ethereum specs and is unlikely to happen due to hash collision.)

For example,

Ethereum execution spaces

After creating the address (contract_address) with create or create2, the function generic_create() is invoked without validation of the newly created address in the precompile contract addresses.

Go Ethereum

There is no check to ensure the newly created address passed into the function is not one of the precompile contract addresses.

https://github.com/ethereum/go-ethereum/blob/293a300d64be3d9a1c2cc92c26fcff4089deadcd/core/vm/evm.go#L418

Impact Details

In case that the newly created contract address belongs to the precompile contract addresses, the contract deployment fails but it succeeds in other clients. However, this is unlikely to happen due to the hardness of the hash collision.

References

  • https://github.com/bluealloy/revm/tree/v50

  • https://github.com/ethereum/execution-specs

  • https://github.com/ethereum/go-ethereum/tree/v1.14.12

Proof of Concept

Proof of Concept

For simplicity, we modify the code inside the make_create_frame( ) to mimic that the newly created address is 0x08 (a precommplile contract address) and perform the testing.

Run the following test case to show that the 0x08 address is not allowed to be deployed with contract:

The test result shows the create collision error occurs:

Was this helpful?