Deploying a Smart Contract at the Same Address as Another Contract on a Different Chain

Hello everyone,

I'm facing a challenge and would appreciate any assistance or guidance. I need to deploy a smart contract to a specific address on one blockchain (Basechain) where a different contract already exists at that same address on another blockchain (Arbitrum). Here's a bit more context:

  1. Scenario:
  • I accidentally sent some ETH to this address on Basechain, but no contract was deployed there initially.
  1. Objective:
  • I want to deploy a RecoverFunds smart contract on Basechain at the exact address to retrieve the funds.
  1. Approach:
  • I’m using the CREATE2 opcode to ensure the smart contract is deployed at the precise address.
  • I’ve written a DeployFactory contract to facilitate this, but I need to find the correct salt to achieve the desired address.
  • I deployed a Router Uni v2 contract address on Arbitrum network.

Issue

Despite running a script on my side, I am unable to deploy the contract at the desired address. The script either runs indefinitely or fails to find the correct salt.

Request

  • Is there a more efficient way to find the correct salt for the CREATE2 deployment?
  • Can the existing deployment on another chain help in calculating the correct salt or bytecode?
  • Any optimization tips or alternative methods to ensure the contract is deployed at the exact address?

Thank you in advance for your assistance!

Here’s the DeployFactory and RecoverFunds contracts I'm working with

DeployFactory.sol:

pragma solidity ^0.8.0;

contract DeployFactory {
    event Deployed(address addr, uint256 salt);

    function deploy(bytes32 salt, bytes memory bytecode) public returns (address) {
        address addr;
        assembly {
            addr := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
            if iszero(extcodesize(addr)) {
                revert(0, 0)
            }
        }
        emit Deployed(addr, uint256(salt));
        return addr;
    }

    function computeAddress(bytes32 salt, bytes32 bytecodeHash) public view returns (address) {
        return address(uint160(uint256(keccak256(abi.encodePacked(byte(0xff), address(this), salt, bytecodeHash)))));
    }
}```


RecoverFunds.sol : 

> // SPDX-License-Identifier: MIT
> pragma solidity ^0.8.0;
> 
> contract RecoverFunds {
>     address public owner;
> 
>     event WithdrawETH(address indexed to, uint256 amount);

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not the contract owner");
        _;
    }

    function withdrawETH() external onlyOwner {
        uint256 balance = address(this).balance;
        require(balance > 0, "No ETH to withdraw");

        (bool success, ) = msg.sender.call{value: balance}("");
        require(success, "ETH withdrawal failed");

        emit WithdrawETH(msg.sender, balance);
    }

    receive() external payable {}
    fallback() external payable {}
}
1 Like

did you deploy the contract on Arbitrum using CREATE2? Did you deploy it using your address directly or throw another contract?

the address of a contract with normal creation (not CREATE2) is calcuated based on the address of sender and its nonce at the time of sending the transaction.

No I deployed a router uniswap v2 contract address on Arbitrum without using CREATE2. I am looking for a way to deploy a recover fund contract on this same adress on Basechain to try to get back my ETH.

what is your nonce on arbitrum and what is your nonce on Basechain?. The nonce of your account currently not the smart contract.

WARNING try please anything you want on a forked network , not real network. otherwise you could skip the required nonce and you will never get the same contract again.

Yes I think it will be impossible ;'(

Nounce 2 on Arbitrum
Nounce 58 on Base