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

Example usage of CREATE2 deployer proxy #1003

Closed

Conversation

saucepoint
Copy link

Providing an example of how to use the CREATE2 deployer proxy

Comment on lines +44 to +68
```solidity
address CREATE2_DEPLOYER = address(0x4e59b44847b379578588920cA78FbF26c0B4956C);

uint256 salt = 100;

// Counter accepts uint256 in its constructor
bytes memory creationCode = abi.encodePacked(type(Counter).creationCode, abi.encode(uint256(200)));

// Precomputing the address of the contract
address counterAddress = address(
uint160(uint256(keccak256(abi.encodePacked(
bytes1(0xff),
CREATE2_DEPLOYER,
salt,
keccak256(creationCode)
))))
);

// deploying `Counter` with CREATE2 and salt
(bool success, ) = CREATE2_DEPLOYER.call(
abi.encodePacked(salt, creationCode)
);
require(success, "Deployment failed");
require(counterAddress.code.length > 0, "Contract not deployed");
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what this code snippet is for? From solidity scripts and tests, you should never need to manually encode this way if you want to use the create2 deploy. new Counter{salt: mySalt}() is all you need

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh interesting, TIL!

Looks like new Counter{salt: mySalt}() works as expected in a script running against anvil, but doesnt seem to work in forge-test. The snippet I provided works in both

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should work in forge test as long as the deployer is there locally. If it's not, I'd suggest "deploying" it with vm.etch("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"), where that code is the deployed bytecode from https://etherscan.io/address/0x4e59b44847b379578588920ca78fbf26c0b4956c.

Copy link
Author

@saucepoint saucepoint Sep 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isnt the deployer already available in forge test if the verbose snippet works? either way tried etching the bytecode and still getting smacked around 🤕

script (works): https://github.com/saucepoint/v4-template/blob/create2-test/script/Counter.s.sol#L23-L36

test (fails): https://github.com/saucepoint/v4-template/blob/create2-test/test/Counter.t.sol#L36-L48

and https://github.com/saucepoint/v4-template/blob/create2-test/test/utils/HookDeployer.sol#L26-L51

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is failing from HookAddressNotValid though, which seems unrelated to the create2 deployer? (unless the address is being computed wrong and using the wrong deployer address)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was mostly confused why the same code in forge script and forge test had different outcomes. Turns out calculating salts / precomputed addresses have different behaviors in script and test


Assume:

    /// @notice Precompute a contract address deployed via CREATE2
    function computeAddress(address deployer, uint256 salt, bytes memory creationCode) public pure returns (address) {
        return address(
            uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, keccak256(creationCode)))))
        );
    }

in forge script you need to provide deployer = 0x4e59b44847b379578588920cA78FbF26c0B4956C

in forge test you need to provide deployer = address(this) (or the pranking address)


willing to update the docs with my findings if you think this is worthwhile information

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yea this is a known issue and we should update tests to use the same create2 deployer as scripts, ref foundry-rs/foundry#5529. cc @Evalir

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now resolved with the always_use_create_2_factory flag introduced in foundry-rs/foundry#6656

require(success, "Deployment failed");
require(counterAddress.code.length > 0, "Contract not deployed");
```

#### Supported RPC Methods
##### Standard Methods
The standard methods are based on [this](https://eth.wiki/json-rpc/API) reference.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

نسخة مكررة من #

@onbjerg
Copy link
Member

onbjerg commented Mar 14, 2024

Hey, what is needed to get this over the line? @mds1 @saucepoint

@saucepoint
Copy link
Author

@onbjerg i need to redo the PR to communicate the deployer proxy address should be used when computing the mined address

@onbjerg
Copy link
Member

onbjerg commented Sep 20, 2024

Closing this as stale, feel free to re-open it if progress is made on it:)

@onbjerg onbjerg closed this Sep 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants