Skip to content

Commit

Permalink
Use the deterministic deployer when broadcasting with CREATE2 (#11915)
Browse files Browse the repository at this point in the history
  • Loading branch information
mslipper authored Sep 15, 2024
1 parent 8341f34 commit 92ed64e
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 4 deletions.
9 changes: 9 additions & 0 deletions op-chain-ops/script/deterministic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
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")
)
7 changes: 7 additions & 0 deletions op-chain-ops/script/prank.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
14 changes: 14 additions & 0 deletions op-chain-ops/script/script.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down
10 changes: 6 additions & 4 deletions op-chain-ops/script/script_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)

Expand All @@ -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))
}

0 comments on commit 92ed64e

Please sign in to comment.