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:
- Scenario:
- I accidentally sent some ETH to this address on Basechain, but no contract was deployed there initially.
- Objective:
- I want to deploy a
RecoverFunds
smart contract on Basechain at the exact address to retrieve the funds.
- 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 {}
}