Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Idea] Alternative contract address assignment scheme as replay protection #3583

Closed
Dexaran opened this issue May 21, 2021 · 5 comments
Closed
Labels

Comments

@Dexaran
Copy link
Contributor

Dexaran commented May 21, 2021


eip: ?
title: Alternative contract address assignment scheme
author: Dexaran (@Dexaran) dexaran@ethereumclassic.org
status: Idea
type: Core
category: ERC
created: 2021-05-21

Abstract

The following describes an issue with the method of assigning a contract address during deployment and a proposed solution that might be implemented.

Motivation

The problem: the addresses on the Ethereum chain are stuck with a lot of funds that were originally supposed to be sent to smart-contracts deployed on other networks.

This is a problem of "cross chain address collisions".

There are multiple chains that are based on Ethereum code (example: ETC chain) therefore the same address is valid on both chains. EIP-155 implements chain IDs to prevent transactions from being replayed to the other chain however this does not solve all the problems.

The problem of cross chain collisions is still relevant (here you can see an example of a documented collision that resulted in a loss of $359,708 USD 3 years ago).

The funds are sometimes sent to the address of a smart-contract that is deployed on another chain as a result of a user mistake or software fault.

Example: a user wants to deposit 1 ETC to some contract at ETC chain but he makes a mistake and sends 1 ETH to the same address at ETH chain.

Such transactions happen periodically and the problem can only be solved by deploying a "mock" contract on the other chain (in this case at ETH chain).

It is possible to deploy the contract at the same address by using the account that deployed the original contract. The address assigned to the contract upon deployment depends on (1) the address that creates the contract and (2) the nonce of the transaction keccak256(rlp([sender, nonce])). As the result, the nonce of the account at the ETH chain must not be greater than the nonce of the contract creation transaction at the other chain. Otherwise the contract creator is unable to deploy the mock contract at ETH chain.

In fact, the address of the contract is absolutely irrelevant except for this particular situation. Therefore, I believe that it would be reasonable to provide the ability to use an arbitrary number instead of "nonce", thus allowing the account owner to define the contract address on his own. This can help resolving the problem of cross chain collisions and enable contract developers to extract the users funds that suffered from this issue.

Specification

Adds a new opcode (CREATE3), which takes 4 stack arguments: endowment, memory_start, memory_length, salt. Behaves identically to CREATE (0xf0) but uses salt instead of nonce to generate address of a new contract keccak256(rlp([sender, salt])) and the create-operation fails if the EXTCODESIZE at address keccak256(rlp([sender, salt])) is nonzero.

Rationale

This is the simplest approach of enabling the owner of the original contract to create a copy of it (or a mock contract) at another chain. This is important to consider that only the owner of the original contract must have the ability to deploy contract at this address so this scheme seems to be the most applicable.

Backwards Compatibility

The proposal introduces a new opcode.

Test Cases

N/A

Reference Implementation

N/A

Security Considerations

There are no known security considerations with this EIP.

Copyright Waiver

Copyright and related rights waived via CC0.

@axic
Copy link
Member

axic commented May 21, 2021

Only commenting on the technical aspect of the specification:

  1. Currently contracts created with CREATE2 are "resurrectable", but those created with CREATE are not. This would change this property.
  2. Need to properly describe what happens to CREATE and the external create transaction in case it hits the same address.

Are you sure there is absolutely no backwards compatibility and security issue at play here?

@Dexaran
Copy link
Contributor Author

Dexaran commented May 24, 2021

@axic

Currently contracts created with CREATE2 are "resurrectable", but those created with CREATE are not. This would change this property.

Does "resurrectable" refer a situation where the smart-contract owner can cause contract to SELFDESTRUCT and nullify ​its code and then deploy a new one at the same address?

I would say that it will be possible to "replace" the contract using CREATE3, if the contract allows for this by implementing a "suicide" function the execution of which is not restricted by any internal logic of the contract.

I expect that "code is law" paradigm fans will hate me however I can argue that the proposal does not change any paradigm here. If you don't want contract to be resurrectable then you don't implement suicide function. Anyways, most contracts are not destructible nor they intended to be.

Personally I don't see anything wrong with "destroy & create3-deploy" pattern of updating contract code.

Need to properly describe what happens to CREATE and the external create transaction in case it hits the same address.

Good point.

I'm trying to propose a solution for a problem of cross-chain address collisions. Technically the problem can be solved if we only allow a user to deploy contracts using CREATE3 if salt < nonce. In this case a user will be allowed to deploy contracts at addresses that he "could" potentially achieve with CREATE. At the other hand the situation where CREATE deployment will collide with an already-existing CREATE3-deployed contract will not be possible.

Anyway, I would like to hear community feedback on how best to resolve CREATE / CREATE3 relations - possibly there are better ideas.

Are you sure there is absolutely no backwards compatibility and security issue at play here?

If something relied on the assumption that a contract can be permanently destroyed and once it has zero bytecode size it is no longer viable then this thing can be confused now.

This is a weird pattern of interacting between contracts however. I would like to get feedbacks on this as well.

@martintychan
Copy link

I have suffered from this issue (I had a transaction that was intended for another chain but got it on ETH chain and therefore lost a ETH in the address of a contract which is deployed at the other chain) and I hope that the solution will be implemented, not just for me but also thousands of people like me who suffer from the same issue out there.

@github-actions
Copy link

There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added the stale label Oct 24, 2021
@github-actions
Copy link

github-actions bot commented Nov 7, 2021

This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment.

@github-actions github-actions bot closed this as completed Nov 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants