Commit 92ed64e1 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

Use the deterministic deployer when broadcasting with CREATE2 (#11915)

parent 8341f340
package script
import "github.com/ethereum/go-ethereum/common"
var (
// DeterministicDeployerAddress is the address of the deterministic deployer Forge uses
// to provide deterministic contract addresses.
DeterministicDeployerAddress = common.HexToAddress("0x4e59b44847b379578588920ca78fbf26c0b4956c")
)
......@@ -54,6 +54,13 @@ func (h *Host) handleCaller(caller vm.ContractRef) vm.ContractRef {
if len(h.callStack) > 0 {
parentCallFrame := h.callStack[len(h.callStack)-1]
if parentCallFrame.Prank != nil && caller.Address() != VMAddr { // pranks do not apply to the cheatcode precompile
if parentCallFrame.Prank.Broadcast && parentCallFrame.LastOp == vm.CREATE2 && h.useCreate2Deployer {
return &prankRef{
prank: DeterministicDeployerAddress,
ref: caller,
}
}
if parentCallFrame.Prank.Sender != nil {
return &prankRef{
prank: *parentCallFrame.Prank.Sender,
......
......@@ -105,6 +105,10 @@ type Host struct {
// and prepare the ephemeral tx context again,
// to make gas accounting of a broadcast sub-call more accurate.
isolateBroadcasts bool
// useCreate2Deployer uses the Create2Deployer for broadcasted
// create2 calls.
useCreate2Deployer bool
}
type HostOption func(h *Host)
......@@ -132,6 +136,16 @@ func WithIsolatedBroadcasts() HostOption {
}
}
// WithCreate2Deployer proxies each CREATE2 call through the CREATE2 deployer
// contract located at 0x4e59b44847b379578588920cA78FbF26c0B4956C. This is the Arachnid
// Create2Deployer contract Forge uses. See https://github.com/Arachnid/deterministic-deployment-proxy
// for the implementation.
func WithCreate2Deployer() HostOption {
return func(h *Host) {
h.useCreate2Deployer = true
}
}
// NewHost creates a Host that can load contracts from the given Artifacts FS,
// and with an EVM initialized to the given executionContext.
// Optionally src-map loading may be enabled, by providing a non-nil srcFS to read sources from.
......
......@@ -117,8 +117,8 @@ func TestScriptBroadcast(t *testing.T) {
Nonce: 0, // first action of 0x123456
},
{
From: cafeAddr,
To: crypto.CreateAddress2(cafeAddr, salt, crypto.Keccak256(expectedInitCode)),
From: DeterministicDeployerAddress,
To: crypto.CreateAddress2(DeterministicDeployerAddress, salt, crypto.Keccak256(expectedInitCode)),
Input: expectedInitCode,
Value: (*hexutil.U256)(uint256.NewInt(0)),
Type: BroadcastCreate2,
......@@ -141,7 +141,7 @@ func TestScriptBroadcast(t *testing.T) {
hook := func(broadcast Broadcast) {
broadcasts = append(broadcasts, broadcast)
}
h := NewHost(logger, af, nil, DefaultContext, WithBroadcastHook(hook))
h := NewHost(logger, af, nil, DefaultContext, WithBroadcastHook(hook), WithCreate2Deployer())
addr, err := h.LoadContract("ScriptExample.s.sol", "ScriptExample")
require.NoError(t, err)
......@@ -164,5 +164,7 @@ func TestScriptBroadcast(t *testing.T) {
require.EqualValues(t, 0, h.GetNonce(senderAddr))
require.EqualValues(t, 3, h.GetNonce(scriptAddr))
require.EqualValues(t, 2, h.GetNonce(coffeeAddr))
require.EqualValues(t, 1, h.GetNonce(cafeAddr))
// This is zero because the deterministic deployer is the
// address that actually deploys the contract using CREATE2.
require.EqualValues(t, 0, h.GetNonce(cafeAddr))
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment