Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
dc3922cf
Unverified
Commit
dc3922cf
authored
Jun 26, 2023
by
Mark Tyneway
Committed by
GitHub
Jun 26, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6145 from ethereum-optimism/feat/checkl2
feat: golang checkl2 script
parents
0119b6c2
7648c1de
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
932 additions
and
739 deletions
+932
-739
config.yml
.circleci/config.yml
+4
-9
main.go
op-chain-ops/cmd/check-l2/main.go
+748
-0
helpers.go
op-chain-ops/genesis/helpers.go
+1
-1
layer_two.go
op-chain-ops/genesis/layer_two.go
+1
-1
util.go
op-chain-ops/util/util.go
+178
-0
check-l2.ts
packages/contracts-bedrock/tasks/check-l2.ts
+0
-727
index.ts
packages/contracts-bedrock/tasks/index.ts
+0
-1
No files found.
.circleci/config.yml
View file @
dc3922cf
...
...
@@ -861,8 +861,8 @@ jobs:
make devnet-up-deploy
-
run
:
name
:
Check L2 config
command
:
npx hardhat check-l2 --network devnetL1
--l2-rpc-url http://localhost:9545 --l1-rpc-url http://localhost:8545
working_directory
:
packages/contracts-bedrock
command
:
go run cmd/check-l2/main.go
--l2-rpc-url http://localhost:9545 --l1-rpc-url http://localhost:8545
working_directory
:
op-chain-ops
-
run
:
name
:
Deposit ERC20 through the bridge
command
:
timeout 8m npx hardhat deposit-erc20 --network devnetL1 --l1-contracts-json-path ../../.devnet/sdk-addresses.json
...
...
@@ -907,13 +907,8 @@ jobs:
make devnet-up
-
run
:
name
:
Check L2 config
command
:
|
npx hardhat check-l2 \
--network devnetL1 \
--l2-rpc-url http://localhost:9545 \
--l1-rpc-url http://localhost:8545 \
--l2-output-oracle-address 0x6900000000000000000000000000000000000000
working_directory
:
packages/contracts-bedrock
command
:
go run cmd/check-l2/main.go --l2-rpc-url http://localhost:9545 --l1-rpc-url http://localhost:8545
working_directory
:
op-chain-ops
-
run
:
name
:
Deposit ERC20 through the bridge
command
:
timeout 10m npx hardhat deposit-erc20 --network devnetL1
...
...
op-chain-ops/cmd/check-l2/main.go
0 → 100644
View file @
dc3922cf
package
main
import
(
"bytes"
"context"
"errors"
"fmt"
"math/big"
"os"
"golang.org/x/sync/errgroup"
"github.com/mattn/go-isatty"
"github.com/urfave/cli/v2"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/util"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)
var
defaultCrossDomainMessageSender
=
common
.
HexToAddress
(
"0x000000000000000000000000000000000000dead"
)
// Default script for checking that L2 has been configured correctly. This should be extended in the future
// to pull in L1 deploy artifacts and assert that the L2 state is consistent with the L1 state.
func
main
()
{
log
.
Root
()
.
SetHandler
(
log
.
StreamHandler
(
os
.
Stderr
,
log
.
TerminalFormat
(
isatty
.
IsTerminal
(
os
.
Stderr
.
Fd
()))))
flags
:=
[]
cli
.
Flag
{}
flags
=
append
(
flags
,
util
.
ClientsFlags
...
)
flags
=
append
(
flags
,
util
.
AddressesFlags
...
)
app
:=
&
cli
.
App
{
Name
:
"check-l2"
,
Usage
:
"Check that an OP Stack L2 has been configured correctly"
,
Flags
:
flags
,
Action
:
func
(
ctx
*
cli
.
Context
)
error
{
clients
,
err
:=
util
.
NewClients
(
ctx
)
if
err
!=
nil
{
return
err
}
log
.
Info
(
"Checking predeploy proxy config"
)
g
:=
new
(
errgroup
.
Group
)
// Check that all proxies are configured correctly
// Do this in parallel but not too quickly to allow for
// querying against rate limiting RPC backends
count
:=
uint64
(
2048
)
for
i
:=
uint64
(
0
);
i
<
count
;
i
++
{
i
:=
i
if
i
%
4
==
0
{
log
.
Info
(
"Checking proxy"
,
"index"
,
i
,
"total"
,
count
)
if
err
:=
g
.
Wait
();
err
!=
nil
{
return
err
}
}
g
.
Go
(
func
()
error
{
return
checkPredeploy
(
clients
.
L2Client
,
i
)
})
}
if
err
:=
g
.
Wait
();
err
!=
nil
{
return
err
}
log
.
Info
(
"All predeploy proxies are set correctly"
)
// Check that all of the defined predeploys are set up correctly
for
name
,
addr
:=
range
predeploys
.
Predeploys
{
log
.
Info
(
"Checking predeploy"
,
"name"
,
name
,
"address"
,
addr
.
Hex
())
if
err
:=
checkPredeployConfig
(
clients
.
L2Client
,
name
);
err
!=
nil
{
return
err
}
}
return
nil
},
}
if
err
:=
app
.
Run
(
os
.
Args
);
err
!=
nil
{
log
.
Crit
(
"error indexing state"
,
"err"
,
err
)
}
}
// checkPredeployConfig checks that the defined predeploys are configured correctly
func
checkPredeployConfig
(
client
*
ethclient
.
Client
,
name
string
)
error
{
predeploy
:=
predeploys
.
Predeploys
[
name
]
if
predeploy
==
nil
{
return
fmt
.
Errorf
(
"unknown predeploy %s"
,
name
)
}
p
:=
*
predeploy
g
:=
new
(
errgroup
.
Group
)
if
predeploys
.
IsProxied
(
p
)
{
// Check that an implementation is set. If the implementation has been upgraded,
// it will be considered non-standard. Ensure that there is code set at the implementation.
g
.
Go
(
func
()
error
{
impl
,
err
:=
getEIP1967ImplementationAddress
(
client
,
p
)
if
err
!=
nil
{
return
err
}
log
.
Info
(
name
,
"implementation"
,
impl
.
Hex
())
standardImpl
,
err
:=
genesis
.
AddressToCodeNamespace
(
p
)
if
err
!=
nil
{
return
err
}
if
impl
!=
standardImpl
{
log
.
Warn
(
"%s does not have the standard implementation"
,
name
)
}
implCode
,
err
:=
client
.
CodeAt
(
context
.
Background
(),
impl
,
nil
)
if
err
!=
nil
{
return
err
}
if
len
(
implCode
)
==
0
{
return
fmt
.
Errorf
(
"%s implementation is not deployed"
,
name
)
}
return
nil
})
// Ensure that the code is set to the proxy bytecode as expected
g
.
Go
(
func
()
error
{
proxyCode
,
err
:=
client
.
CodeAt
(
context
.
Background
(),
p
,
nil
)
if
err
!=
nil
{
return
err
}
proxy
,
err
:=
bindings
.
GetDeployedBytecode
(
"Proxy"
)
if
err
!=
nil
{
return
err
}
if
!
bytes
.
Equal
(
proxyCode
,
proxy
)
{
return
fmt
.
Errorf
(
"%s does not have the standard proxy code"
,
name
)
}
return
nil
})
}
// Check the predeploy specific config is correct
g
.
Go
(
func
()
error
{
switch
p
{
case
predeploys
.
LegacyMessagePasserAddr
:
if
err
:=
checkLegacyMessagePasser
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
DeployerWhitelistAddr
:
if
err
:=
checkDeployerWhitelist
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
L2CrossDomainMessengerAddr
:
if
err
:=
checkL2CrossDomainMessenger
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
GasPriceOracleAddr
:
if
err
:=
checkGasPriceOracle
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
L2StandardBridgeAddr
:
if
err
:=
checkL2StandardBridge
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
SequencerFeeVaultAddr
:
if
err
:=
checkSequencerFeeVault
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
OptimismMintableERC20FactoryAddr
:
if
err
:=
checkOptimismMintableERC20Factory
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
L1BlockNumberAddr
:
if
err
:=
checkL1BlockNumber
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
L1BlockAddr
:
if
err
:=
checkL1Block
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
WETH9Addr
:
if
err
:=
checkWETH9
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
GovernanceTokenAddr
:
if
err
:=
checkGovernanceToken
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
L2ERC721BridgeAddr
:
if
err
:=
checkL2ERC721Bridge
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
OptimismMintableERC721FactoryAddr
:
if
err
:=
checkOptimismMintableERC721Factory
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
ProxyAdminAddr
:
if
err
:=
checkProxyAdmin
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
BaseFeeVaultAddr
:
if
err
:=
checkBaseFeeVault
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
L1FeeVaultAddr
:
if
err
:=
checkL1FeeVault
(
p
,
client
);
err
!=
nil
{
return
err
}
case
predeploys
.
L2ToL1MessagePasserAddr
:
if
err
:=
checkL2ToL1MessagePasser
(
p
,
client
);
err
!=
nil
{
return
err
}
}
return
nil
})
if
err
:=
g
.
Wait
();
err
!=
nil
{
return
err
}
return
nil
}
func
checkL2ToL1MessagePasser
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewL2ToL1MessagePasser
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
messageVersion
,
err
:=
contract
.
MESSAGEVERSION
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2ToL1MessagePasser"
,
"MESSAGE_VERSION"
,
messageVersion
)
messageNonce
,
err
:=
contract
.
MessageNonce
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2ToL1MessagePasser"
,
"MESSAGE_NONCE"
,
messageNonce
)
return
nil
}
func
checkL1FeeVault
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewL1FeeVault
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
recipient
,
err
:=
contract
.
RECIPIENT
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L1FeeVault"
,
"RECIPIENT"
,
recipient
.
Hex
())
if
recipient
==
(
common
.
Address
{})
{
return
errors
.
New
(
"RECIPIENT should not be address(0)"
)
}
minWithdrawalAmount
,
err
:=
contract
.
MINWITHDRAWALAMOUNT
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L1FeeVault"
,
"MIN_WITHDRAWAL_AMOUNT"
,
minWithdrawalAmount
)
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L1FeeVault version"
,
"version"
,
version
)
return
nil
}
func
checkBaseFeeVault
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewBaseFeeVault
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
recipient
,
err
:=
contract
.
RECIPIENT
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"BaseFeeVault"
,
"RECIPIENT"
,
recipient
.
Hex
())
if
recipient
==
(
common
.
Address
{})
{
return
errors
.
New
(
"RECIPIENT should not be address(0)"
)
}
minWithdrawalAmount
,
err
:=
contract
.
MINWITHDRAWALAMOUNT
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"BaseFeeVault"
,
"MIN_WITHDRAWAL_AMOUNT"
,
minWithdrawalAmount
)
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"BaseFeeVault version"
,
"version"
,
version
)
return
nil
}
func
checkProxyAdmin
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewProxyAdmin
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
owner
,
err
:=
contract
.
Owner
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"ProxyAdmin"
,
"owner"
,
owner
.
Hex
())
if
owner
==
(
common
.
Address
{})
{
return
errors
.
New
(
"ProxyAdmin.owner is zero address"
)
}
addressManager
,
err
:=
contract
.
AddressManager
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"ProxyAdmin"
,
"addressManager"
,
addressManager
.
Hex
())
return
nil
}
func
checkOptimismMintableERC721Factory
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewOptimismMintableERC721Factory
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
bridge
,
err
:=
contract
.
BRIDGE
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"OptimismMintableERC721Factory"
,
"BRIDGE"
,
bridge
.
Hex
())
if
bridge
==
(
common
.
Address
{})
{
return
errors
.
New
(
"OptimismMintableERC721Factory.BRIDGE is zero address"
)
}
remoteChainID
,
err
:=
contract
.
REMOTECHAINID
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"OptimismMintableERC721Factory"
,
"REMOTE_CHAIN_ID"
,
remoteChainID
)
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"OptimismMintableERC721Factory version"
,
"version"
,
version
)
return
nil
}
func
checkL2ERC721Bridge
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewL2ERC721Bridge
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
messenger
,
err
:=
contract
.
MESSENGER
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2ERC721Bridge"
,
"MESSENGER"
,
messenger
.
Hex
())
if
messenger
==
(
common
.
Address
{})
{
return
errors
.
New
(
"L2ERC721Bridge.MESSENGER is zero address"
)
}
otherBridge
,
err
:=
contract
.
OTHERBRIDGE
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2ERC721Bridge"
,
"OTHERBRIDGE"
,
otherBridge
.
Hex
())
if
otherBridge
==
(
common
.
Address
{})
{
return
errors
.
New
(
"L2ERC721Bridge.OTHERBRIDGE is zero address"
)
}
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2ERC721Bridge version"
,
"version"
,
version
)
return
nil
}
func
checkGovernanceToken
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
code
,
err
:=
client
.
CodeAt
(
context
.
Background
(),
addr
,
nil
)
if
err
!=
nil
{
return
err
}
if
len
(
code
)
>
0
{
// This should also check the owner
contract
,
err
:=
bindings
.
NewERC20
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
name
,
err
:=
contract
.
Name
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"GovernanceToken"
,
"name"
,
name
)
symbol
,
err
:=
contract
.
Symbol
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"GovernanceToken"
,
"symbol"
,
symbol
)
totalSupply
,
err
:=
contract
.
TotalSupply
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"GovernanceToken"
,
"totalSupply"
,
totalSupply
)
}
else
{
log
.
Info
(
"No code at GovernanceToken"
)
}
return
nil
}
func
checkWETH9
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewWETH9
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
name
,
err
:=
contract
.
Name
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"WETH9"
,
"name"
,
name
)
if
name
!=
"Wrapped Ether"
{
return
fmt
.
Errorf
(
"WETH9 name should be 'Wrapped Ether', got %s"
,
name
)
}
symbol
,
err
:=
contract
.
Symbol
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"WETH9"
,
"symbol"
,
symbol
)
if
symbol
!=
"WETH"
{
return
fmt
.
Errorf
(
"WETH9 symbol should be 'WETH', got %s"
,
symbol
)
}
decimals
,
err
:=
contract
.
Decimals
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"WETH9"
,
"decimals"
,
decimals
)
if
decimals
!=
18
{
return
fmt
.
Errorf
(
"WETH9 decimals should be 18, got %d"
,
decimals
)
}
return
nil
}
func
checkL1Block
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewL1Block
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L1Block version"
,
"version"
,
version
)
return
nil
}
func
checkL1BlockNumber
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewL1BlockNumber
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L1BlockNumber version"
,
"version"
,
version
)
return
nil
}
func
checkOptimismMintableERC20Factory
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewOptimismMintableERC20Factory
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
bridge
,
err
:=
contract
.
BRIDGE
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"OptimismMintableERC20Factory"
,
"BRIDGE"
,
bridge
.
Hex
())
if
bridge
==
(
common
.
Address
{})
{
return
errors
.
New
(
"OptimismMintableERC20Factory.BRIDGE is zero address"
)
}
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"OptimismMintableERC20Factory version"
,
"version"
,
version
)
return
nil
}
func
checkSequencerFeeVault
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewSequencerFeeVault
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
recipient
,
err
:=
contract
.
RECIPIENT
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"SequencerFeeVault"
,
"RECIPIENT"
,
recipient
.
Hex
())
if
recipient
==
(
common
.
Address
{})
{
return
errors
.
New
(
"RECIPIENT should not be address(0)"
)
}
l1FeeWallet
,
err
:=
contract
.
L1FeeWallet
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"SequencerFeeVault"
,
"l1FeeWallet"
,
l1FeeWallet
.
Hex
())
minWithdrawalAmount
,
err
:=
contract
.
MINWITHDRAWALAMOUNT
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"SequencerFeeVault"
,
"MIN_WITHDRAWAL_AMOUNT"
,
minWithdrawalAmount
)
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"SequencerFeeVault version"
,
"version"
,
version
)
return
nil
}
func
checkL2StandardBridge
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewL2StandardBridge
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
otherBridge
,
err
:=
contract
.
OTHERBRIDGE
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
if
otherBridge
==
(
common
.
Address
{})
{
return
errors
.
New
(
"OTHERBRIDGE should not be address(0)"
)
}
log
.
Info
(
"L2StandardBridge"
,
"OTHERBRIDGE"
,
otherBridge
.
Hex
())
messenger
,
err
:=
contract
.
MESSENGER
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2StandardBridge"
,
"MESSENGER"
,
messenger
.
Hex
())
if
messenger
!=
predeploys
.
L2CrossDomainMessengerAddr
{
return
fmt
.
Errorf
(
"L2StandardBridge MESSENGER should be %s, got %s"
,
predeploys
.
L2CrossDomainMessengerAddr
,
messenger
)
}
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2StandardBridge version"
,
"version"
,
version
)
return
nil
}
func
checkGasPriceOracle
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewGasPriceOracle
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
decimals
,
err
:=
contract
.
DECIMALS
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"GasPriceOracle"
,
"DECIMALS"
,
decimals
)
if
decimals
.
Cmp
(
big
.
NewInt
(
6
))
!=
0
{
return
fmt
.
Errorf
(
"GasPriceOracle decimals should be 6, got %v"
,
decimals
)
}
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"GasPriceOracle version"
,
"version"
,
version
)
return
nil
}
func
checkL2CrossDomainMessenger
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
slot
,
err
:=
client
.
StorageAt
(
context
.
Background
(),
addr
,
common
.
Hash
{
31
:
0xcc
},
nil
)
if
err
!=
nil
{
return
err
}
if
common
.
BytesToAddress
(
slot
)
!=
defaultCrossDomainMessageSender
{
return
fmt
.
Errorf
(
"Expected xDomainMsgSender to be %s, got %s"
,
defaultCrossDomainMessageSender
,
addr
)
}
contract
,
err
:=
bindings
.
NewL2CrossDomainMessenger
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
otherMessenger
,
err
:=
contract
.
OTHERMESSENGER
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
if
otherMessenger
==
(
common
.
Address
{})
{
return
errors
.
New
(
"OTHERMESSENGER should not be address(0)"
)
}
log
.
Info
(
"L2CrossDomainMessenger"
,
"OTHERMESSENGER"
,
otherMessenger
.
Hex
())
l1CrossDomainMessenger
,
err
:=
contract
.
L1CrossDomainMessenger
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2CrossDomainMessenger"
,
"l1CrossDomainMessenger"
,
l1CrossDomainMessenger
.
Hex
())
messageVersion
,
err
:=
contract
.
MESSAGEVERSION
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2CrossDomainMessenger"
,
"MESSAGE_VERSION"
,
messageVersion
)
minGasCallDataOverhead
,
err
:=
contract
.
MINGASCALLDATAOVERHEAD
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2CrossDomainMessenger"
,
"MIN_GAS_CALLDATA_OVERHEAD"
,
minGasCallDataOverhead
)
relayConstantOverhead
,
err
:=
contract
.
RELAYCONSTANTOVERHEAD
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2CrossDomainMessenger"
,
"RELAY_CONSTANT_OVERHEAD"
,
relayConstantOverhead
)
minGasDynamicsOverheadDenominator
,
err
:=
contract
.
MINGASDYNAMICOVERHEADDENOMINATOR
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2CrossDomainMessenger"
,
"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR"
,
minGasDynamicsOverheadDenominator
)
minGasDynamicsOverheadNumerator
,
err
:=
contract
.
MINGASDYNAMICOVERHEADNUMERATOR
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2CrossDomainMessenger"
,
"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR"
,
minGasDynamicsOverheadNumerator
)
relayCallOverhead
,
err
:=
contract
.
RELAYCALLOVERHEAD
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2CrossDomainMessenger"
,
"RELAY_CALL_OVERHEAD"
,
relayCallOverhead
)
relayReservedGas
,
err
:=
contract
.
RELAYRESERVEDGAS
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2CrossDomainMessenger"
,
"RELAY_RESERVED_GAS"
,
relayReservedGas
)
relayGasCheckBuffer
,
err
:=
contract
.
RELAYGASCHECKBUFFER
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2CrossDomainMessenger"
,
"RELAY_GAS_CHECK_BUFFER"
,
relayGasCheckBuffer
)
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"L2CrossDomainMessenger version"
,
"version"
,
version
)
return
nil
}
func
checkLegacyMessagePasser
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewLegacyMessagePasser
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"LegacyMessagePasser version"
,
"version"
,
version
)
return
nil
}
func
checkDeployerWhitelist
(
addr
common
.
Address
,
client
*
ethclient
.
Client
)
error
{
contract
,
err
:=
bindings
.
NewDeployerWhitelist
(
addr
,
client
)
if
err
!=
nil
{
return
err
}
owner
,
err
:=
contract
.
Owner
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
if
owner
!=
(
common
.
Address
{})
{
return
fmt
.
Errorf
(
"DeployerWhitelist owner should be set to address(0)"
)
}
version
,
err
:=
contract
.
Version
(
&
bind
.
CallOpts
{})
if
err
!=
nil
{
return
err
}
log
.
Info
(
"DeployerWhitelist version"
,
"version"
,
version
)
return
nil
}
func
getEIP1967AdminAddress
(
client
*
ethclient
.
Client
,
addr
common
.
Address
)
(
common
.
Address
,
error
)
{
slot
,
err
:=
client
.
StorageAt
(
context
.
Background
(),
addr
,
util
.
EIP1967AdminSlot
,
nil
)
if
err
!=
nil
{
return
common
.
Address
{},
err
}
admin
:=
common
.
BytesToAddress
(
slot
)
return
admin
,
nil
}
func
getEIP1967ImplementationAddress
(
client
*
ethclient
.
Client
,
addr
common
.
Address
)
(
common
.
Address
,
error
)
{
slot
,
err
:=
client
.
StorageAt
(
context
.
Background
(),
addr
,
util
.
EIP1967ImplementationSlot
,
nil
)
if
err
!=
nil
{
return
common
.
Address
{},
err
}
impl
:=
common
.
BytesToAddress
(
slot
)
return
impl
,
nil
}
// checkPredeploy ensures that the predeploy at index i has the correct proxy admin set
func
checkPredeploy
(
client
*
ethclient
.
Client
,
i
uint64
)
error
{
bigAddr
:=
new
(
big
.
Int
)
.
Or
(
genesis
.
BigL2PredeployNamespace
,
new
(
big
.
Int
)
.
SetUint64
(
i
))
addr
:=
common
.
BigToAddress
(
bigAddr
)
if
!
predeploys
.
IsProxied
(
addr
)
{
return
nil
}
admin
,
err
:=
getEIP1967AdminAddress
(
client
,
addr
)
if
err
!=
nil
{
return
err
}
if
admin
!=
predeploys
.
ProxyAdminAddr
{
return
fmt
.
Errorf
(
"%s does not have correct proxy admin set"
,
addr
)
}
return
nil
}
op-chain-ops/genesis/helpers.go
View file @
dc3922cf
...
...
@@ -21,7 +21,7 @@ var (
// l1PredeployNamespace represents the namespace of L1 predeploys
l1PredeployNamespace
=
common
.
HexToAddress
(
"0x6900000000000000000000000000000000000000"
)
// bigL2PredeployNamespace represents the predeploy namespace as a big.Int
b
igL2PredeployNamespace
=
new
(
big
.
Int
)
.
SetBytes
(
l2PredeployNamespace
.
Bytes
())
B
igL2PredeployNamespace
=
new
(
big
.
Int
)
.
SetBytes
(
l2PredeployNamespace
.
Bytes
())
// bigL1PredeployNamespace represents the predeploy namespace as a big.Int
bigL1PredeployNamespace
=
new
(
big
.
Int
)
.
SetBytes
(
l1PredeployNamespace
.
Bytes
())
// bigCodeNamespace represents the predeploy namespace as a big.Int
...
...
op-chain-ops/genesis/layer_two.go
View file @
dc3922cf
...
...
@@ -36,7 +36,7 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene
}
// Set up the proxies
err
=
setProxies
(
db
,
predeploys
.
ProxyAdminAddr
,
b
igL2PredeployNamespace
,
2048
)
err
=
setProxies
(
db
,
predeploys
.
ProxyAdminAddr
,
B
igL2PredeployNamespace
,
2048
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
op-chain-ops/util/util.go
0 → 100644
View file @
dc3922cf
package
util
import
(
"context"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient/gethclient"
"github.com/ethereum/go-ethereum/rpc"
"github.com/urfave/cli/v2"
)
var
(
// EIP1976ImplementationSlot
EIP1967ImplementationSlot
=
common
.
HexToHash
(
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"
)
// EIP1967AdminSlot
EIP1967AdminSlot
=
common
.
HexToHash
(
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103"
)
)
// clients represents a set of initialized RPC clients
type
Clients
struct
{
L1Client
*
ethclient
.
Client
L2Client
*
ethclient
.
Client
L1RpcClient
*
rpc
.
Client
L2RpcClient
*
rpc
.
Client
L1GethClient
*
gethclient
.
Client
L2GethClient
*
gethclient
.
Client
}
// NewClients will create new RPC clients from a CLI context
func
NewClients
(
ctx
*
cli
.
Context
)
(
*
Clients
,
error
)
{
clients
:=
Clients
{}
l1RpcURL
:=
ctx
.
String
(
"l1-rpc-url"
)
if
l1RpcURL
!=
""
{
l1Client
,
l1RpcClient
,
l1GethClient
,
err
:=
newClients
(
l1RpcURL
)
if
err
!=
nil
{
return
nil
,
err
}
clients
.
L1Client
=
l1Client
clients
.
L1RpcClient
=
l1RpcClient
clients
.
L1GethClient
=
l1GethClient
}
l2RpcURL
:=
ctx
.
String
(
"l2-rpc-url"
)
if
l2RpcURL
!=
""
{
l2Client
,
l2RpcClient
,
l2GethClient
,
err
:=
newClients
(
l2RpcURL
)
if
err
!=
nil
{
return
nil
,
err
}
clients
.
L2Client
=
l2Client
clients
.
L2RpcClient
=
l2RpcClient
clients
.
L2GethClient
=
l2GethClient
}
return
&
clients
,
nil
}
// newClients will create new clients from a given URL
func
newClients
(
url
string
)
(
*
ethclient
.
Client
,
*
rpc
.
Client
,
*
gethclient
.
Client
,
error
)
{
ethClient
,
err
:=
ethclient
.
Dial
(
url
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
fmt
.
Errorf
(
"cannot dial ethclient: %w"
,
err
)
}
rpcClient
,
err
:=
rpc
.
DialContext
(
context
.
Background
(),
url
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
fmt
.
Errorf
(
"cannot dial rpc client: %w"
,
err
)
}
return
ethClient
,
rpcClient
,
gethclient
.
New
(
rpcClient
),
nil
}
// ClientsFlags represent the flags associated with creating RPC clients.
var
ClientsFlags
=
[]
cli
.
Flag
{
&
cli
.
StringFlag
{
Name
:
"l1-rpc-url"
,
Required
:
true
,
Usage
:
"L1 RPC URL"
,
EnvVars
:
[]
string
{
"L1_RPC_URL"
},
},
&
cli
.
StringFlag
{
Name
:
"l2-rpc-url"
,
Required
:
true
,
Usage
:
"L2 RPC URL"
,
EnvVars
:
[]
string
{
"L2_RPC_URL"
},
},
}
// Addresses represents the address values of various contracts. The values can
// be easily populated via a [cli.Context].
type
Addresses
struct
{
AddressManager
common
.
Address
OptimismPortal
common
.
Address
L1StandardBridge
common
.
Address
L1CrossDomainMessenger
common
.
Address
CanonicalTransactionChain
common
.
Address
StateCommitmentChain
common
.
Address
}
// AddressesFlags represent the flags associated with address parsing.
var
AddressesFlags
=
[]
cli
.
Flag
{
&
cli
.
StringFlag
{
Name
:
"address-manager-address"
,
Usage
:
"AddressManager address"
,
EnvVars
:
[]
string
{
"ADDRESS_MANAGER_ADDRESS"
},
},
&
cli
.
StringFlag
{
Name
:
"optimism-portal-address"
,
Usage
:
"OptimismPortal address"
,
EnvVars
:
[]
string
{
"OPTIMISM_PORTAL_ADDRESS"
},
},
&
cli
.
StringFlag
{
Name
:
"l1-standard-bridge-address"
,
Usage
:
"L1StandardBridge address"
,
EnvVars
:
[]
string
{
"L1_STANDARD_BRIDGE_ADDRESS"
},
},
&
cli
.
StringFlag
{
Name
:
"l1-crossdomain-messenger-address"
,
Usage
:
"L1CrossDomainMessenger address"
,
EnvVars
:
[]
string
{
"L1_CROSSDOMAIN_MESSENGER_ADDRESS"
},
},
&
cli
.
StringFlag
{
Name
:
"canonical-transaction-chain-address"
,
Usage
:
"CanonicalTransactionChain address"
,
EnvVars
:
[]
string
{
"CANONICAL_TRANSACTION_CHAIN_ADDRESS"
},
},
&
cli
.
StringFlag
{
Name
:
"state-commitment-chain-address"
,
Usage
:
"StateCommitmentChain address"
,
EnvVars
:
[]
string
{
"STATE_COMMITMENT_CHAIN_ADDRESS"
},
},
}
// NewAddresses populates an Addresses struct given a [cli.Context].
// This is useful for writing scripts that interact with smart contracts.
func
NewAddresses
(
ctx
*
cli
.
Context
)
(
*
Addresses
,
error
)
{
var
addresses
Addresses
var
err
error
addresses
.
AddressManager
,
err
=
parseAddress
(
ctx
,
"address-manager-address"
)
if
err
!=
nil
{
return
nil
,
err
}
addresses
.
OptimismPortal
,
err
=
parseAddress
(
ctx
,
"optimism-portal-address"
)
if
err
!=
nil
{
return
nil
,
err
}
addresses
.
L1StandardBridge
,
err
=
parseAddress
(
ctx
,
"l1-standard-bridge-address"
)
if
err
!=
nil
{
return
nil
,
err
}
addresses
.
L1CrossDomainMessenger
,
err
=
parseAddress
(
ctx
,
"l1-crossdomain-messenger-address"
)
if
err
!=
nil
{
return
nil
,
err
}
addresses
.
CanonicalTransactionChain
,
err
=
parseAddress
(
ctx
,
"canonical-transaction-chain-address"
)
if
err
!=
nil
{
return
nil
,
err
}
addresses
.
StateCommitmentChain
,
err
=
parseAddress
(
ctx
,
"state-commitment-chain-address"
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
addresses
,
nil
}
// parseAddress will parse a [common.Address] from a [cli.Context] and return
// an error if the configured address is not correct.
func
parseAddress
(
ctx
*
cli
.
Context
,
name
string
)
(
common
.
Address
,
error
)
{
value
:=
ctx
.
String
(
name
)
if
value
==
""
{
return
common
.
Address
{},
nil
}
if
!
common
.
IsHexAddress
(
value
)
{
return
common
.
Address
{},
fmt
.
Errorf
(
"invalid address: %s"
,
value
)
}
return
common
.
HexToAddress
(
value
),
nil
}
packages/contracts-bedrock/tasks/check-l2.ts
deleted
100644 → 0
View file @
0119b6c2
import
assert
from
'
assert
'
import
{
task
,
types
}
from
'
hardhat/config
'
import
'
@nomiclabs/hardhat-ethers
'
import
'
hardhat-deploy
'
import
{
HardhatRuntimeEnvironment
}
from
'
hardhat/types
'
import
{
Contract
,
providers
,
Wallet
,
Signer
,
BigNumber
}
from
'
ethers
'
import
{
predeploys
}
from
'
../src
'
// expectedSemver is the semver version of the contracts
// deployed at bedrock deployment
const
expectedSemver
=
'
1.0.0
'
const
implSlot
=
'
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
'
const
adminSlot
=
'
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103
'
const
prefix
=
'
0x420000000000000000000000000000000000
'
const
logLoud
=
()
=>
{
console
.
log
(
'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
'
)
}
const
yell
=
(
msg
:
string
)
=>
{
logLoud
()
console
.
log
(
msg
)
logLoud
()
}
// checkPredeploys will ensure that all of the predeploys are set
const
checkPredeploys
=
async
(
hre
:
HardhatRuntimeEnvironment
,
provider
:
providers
.
Provider
)
=>
{
console
.
log
(
'
Checking predeploys are configured correctly
'
)
const
admin
=
hre
.
ethers
.
utils
.
hexConcat
([
'
0x000000000000000000000000
'
,
predeploys
.
ProxyAdmin
,
])
// We only check predeploys 0x420..00 through 0x420..FF on the mainnet network to
// reduce the probability of an RPC timeout. After the migration, all predeploys
// from 0x420..00 through 0x420..07FF should be checked.
const
maxCheck
=
hre
.
network
.
name
===
'
mainnet
'
?
256
:
2048
const
codeReq
=
[]
const
slotReq
=
[]
// First loop for requests
for
(
let
i
=
0
;
i
<
maxCheck
;
i
++
)
{
const
num
=
hre
.
ethers
.
utils
.
hexZeroPad
(
'
0x
'
+
i
.
toString
(
16
),
2
)
const
addr
=
hre
.
ethers
.
utils
.
getAddress
(
hre
.
ethers
.
utils
.
hexConcat
([
prefix
,
num
])
)
codeReq
.
push
(
provider
.
getCode
(
addr
))
slotReq
.
push
(
provider
.
getStorageAt
(
addr
,
adminSlot
))
}
// Wait for all requests to finish
// The `JsonRpcBatchProvider` will batch requests in the background.
const
codeRes
=
await
Promise
.
all
(
codeReq
)
const
slotRes
=
await
Promise
.
all
(
slotReq
)
// Second loop for response checks
for
(
let
i
=
0
;
i
<
maxCheck
;
i
++
)
{
const
num
=
hre
.
ethers
.
utils
.
hexZeroPad
(
'
0x
'
+
i
.
toString
(
16
),
2
)
const
addr
=
hre
.
ethers
.
utils
.
getAddress
(
hre
.
ethers
.
utils
.
hexConcat
([
prefix
,
num
])
)
if
(
codeRes
[
i
]
===
'
0x
'
)
{
throw
new
Error
(
`no code found at
${
addr
}
`
)
}
if
(
addr
===
predeploys
.
GovernanceToken
||
addr
===
predeploys
.
ProxyAdmin
||
addr
===
predeploys
.
WETH9
)
{
continue
}
if
(
slotRes
[
i
]
!==
admin
)
{
throw
new
Error
(
`incorrect admin slot in
${
addr
}
`
)
}
if
(
i
%
(
maxCheck
/
4
)
===
0
)
{
console
.
log
(
`Checked through
${
addr
}
`
)
}
}
}
// assertSemver will ensure that the semver is the correct version
const
assertSemver
=
async
(
contract
:
Contract
,
name
:
string
,
override
?:
string
)
=>
{
const
version
=
await
contract
.
version
()
let
target
=
expectedSemver
if
(
override
)
{
target
=
override
}
if
(
version
!==
target
)
{
throw
new
Error
(
`
${
name
}
: version mismatch. Got
${
version
}
, expected
${
target
}
`
)
}
console
.
log
(
` - version:
${
version
}
`
)
}
// checkProxy will print out the proxy slots
const
checkProxy
=
async
(
_hre
:
HardhatRuntimeEnvironment
,
name
:
string
,
provider
:
providers
.
Provider
)
=>
{
const
address
=
predeploys
[
name
]
if
(
!
address
)
{
throw
new
Error
(
`unknown contract name:
${
name
}
`
)
}
const
impl
=
await
provider
.
getStorageAt
(
address
,
implSlot
)
const
admin
=
await
provider
.
getStorageAt
(
address
,
adminSlot
)
console
.
log
(
` - EIP-1967 implementation slot:
${
impl
}
`
)
console
.
log
(
` - EIP-1967 admin slot:
${
admin
}
`
)
}
// assertProxy will require the proxy is set
const
assertProxy
=
async
(
hre
:
HardhatRuntimeEnvironment
,
name
:
string
,
provider
:
providers
.
Provider
)
=>
{
const
address
=
predeploys
[
name
]
if
(
!
address
)
{
throw
new
Error
(
`unknown contract name:
${
name
}
`
)
}
const
code
=
await
provider
.
getCode
(
address
)
const
deployInfo
=
await
hre
.
artifacts
.
readArtifact
(
'
Proxy
'
)
if
(
code
!==
deployInfo
.
deployedBytecode
)
{
throw
new
Error
(
`
${
address
}
: code mismatch`
)
}
const
impl
=
await
provider
.
getStorageAt
(
address
,
implSlot
)
const
implAddress
=
'
0x
'
+
impl
.
slice
(
26
)
const
implCode
=
await
provider
.
getCode
(
implAddress
)
if
(
implCode
===
'
0x
'
)
{
throw
new
Error
(
'
No code at implementation
'
)
}
}
// checks to make sure that the genesis magic value
// was set correctly
const
checkGenesisMagic
=
async
(
hre
:
HardhatRuntimeEnvironment
,
l2Provider
:
providers
.
Provider
,
args
)
=>
{
const
magic
=
'
0x
'
+
Buffer
.
from
(
'
BEDROCK
'
).
toString
(
'
hex
'
)
let
startingBlockNumber
:
number
// We have a connection to the L1 chain, fetch the remote value
if
(
args
.
l1RpcUrl
!==
''
)
{
const
l1Provider
=
new
hre
.
ethers
.
providers
.
StaticJsonRpcProvider
(
args
.
l1RpcUrl
)
// Get the address if it was passed in via CLI
// Otherwise get the address from a hardhat deployment file
let
address
:
string
if
(
args
.
l2OutputOracleAddress
!==
''
)
{
address
=
args
.
l2OutputOracleAddress
}
else
{
const
Deployment__L2OutputOracle
=
await
hre
.
deployments
.
get
(
'
L2OutputOracleProxy
'
)
address
=
Deployment__L2OutputOracle
.
address
}
const
abi
=
{
inputs
:
[],
name
:
'
startingBlockNumber
'
,
outputs
:
[{
internalType
:
'
uint256
'
,
name
:
''
,
type
:
'
uint256
'
}],
stateMutability
:
'
view
'
,
type
:
'
function
'
,
}
const
L2OutputOracle
=
new
hre
.
ethers
.
Contract
(
address
,
[
abi
],
l1Provider
)
// In the migration, the L2OutputOracle proxy is not yet initialized when we
// want to run this script. Fall back on the local config if we get an error
// fetching the starting block number.
try
{
startingBlockNumber
=
await
L2OutputOracle
.
startingBlockNumber
()
}
catch
(
e
)
{
console
.
log
(
`Error fetching startingBlockNumber:\n
${
e
.
message
}
`
)
console
.
log
(
'
Falling back to local config.
'
)
startingBlockNumber
=
hre
.
deployConfig
.
l2OutputOracleStartingBlockNumber
}
}
else
{
// We do not have a connection to the L1 chain, use the local config
// The `--network` flag must be set to the L1 network
startingBlockNumber
=
hre
.
deployConfig
.
l2OutputOracleStartingBlockNumber
}
// ensure that the starting block number is a number
startingBlockNumber
=
BigNumber
.
from
(
startingBlockNumber
).
toNumber
()
const
block
=
await
l2Provider
.
getBlock
(
startingBlockNumber
)
const
extradata
=
block
.
extraData
if
(
extradata
!==
magic
)
{
throw
new
Error
(
`magic value in extradata does not match: got
${
extradata
}
, expected
${
magic
}
`
)
}
}
const
check
=
{
// LegacyMessagePasser
// - check version
// - is behind a proxy
LegacyMessagePasser
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
LegacyMessagePasser
=
await
hre
.
ethers
.
getContractAt
(
'
LegacyMessagePasser
'
,
predeploys
.
LegacyMessagePasser
,
signer
)
await
assertSemver
(
LegacyMessagePasser
,
'
LegacyMessagePasser
'
,
'
1.0.1
'
)
await
checkProxy
(
hre
,
'
LegacyMessagePasser
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
LegacyMessagePasser
'
,
signer
.
provider
)
},
// DeployerWhitelist
// - check version
// - is behind a proxy
// - owner is `address(0)`
DeployerWhitelist
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
DeployerWhitelist
=
await
hre
.
ethers
.
getContractAt
(
'
DeployerWhitelist
'
,
predeploys
.
DeployerWhitelist
,
signer
)
await
assertSemver
(
DeployerWhitelist
,
'
DeployerWhitelist
'
,
'
1.0.1
'
)
const
owner
=
await
DeployerWhitelist
.
owner
()
assert
(
owner
===
hre
.
ethers
.
constants
.
AddressZero
)
console
.
log
(
` - owner:
${
owner
}
`
)
await
checkProxy
(
hre
,
'
DeployerWhitelist
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
DeployerWhitelist
'
,
signer
.
provider
)
},
// L2CrossDomainMessenger
// - check version
// - check OTHER_MESSENGER
// - check l1CrossDomainMessenger (legacy)
// - is behind a proxy
// - check owner
// - check initialized
L2CrossDomainMessenger
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
L2CrossDomainMessenger
=
await
hre
.
ethers
.
getContractAt
(
'
L2CrossDomainMessenger
'
,
predeploys
.
L2CrossDomainMessenger
,
signer
)
await
assertSemver
(
L2CrossDomainMessenger
,
'
L2CrossDomainMessenger
'
,
'
1.4.1
'
)
const
xDomainMessageSenderSlot
=
await
signer
.
provider
.
getStorageAt
(
predeploys
.
L2CrossDomainMessenger
,
204
)
const
xDomainMessageSender
=
'
0x
'
+
xDomainMessageSenderSlot
.
slice
(
26
)
assert
(
xDomainMessageSender
===
'
0x000000000000000000000000000000000000dead
'
)
const
otherMessenger
=
await
L2CrossDomainMessenger
.
OTHER_MESSENGER
()
assert
(
otherMessenger
!==
hre
.
ethers
.
constants
.
AddressZero
)
yell
(
` - OTHER_MESSENGER:
${
otherMessenger
}
`
)
const
l1CrossDomainMessenger
=
await
L2CrossDomainMessenger
.
l1CrossDomainMessenger
()
yell
(
` - l1CrossDomainMessenger:
${
l1CrossDomainMessenger
}
`
)
await
checkProxy
(
hre
,
'
L2CrossDomainMessenger
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
L2CrossDomainMessenger
'
,
signer
.
provider
)
const
MESSAGE_VERSION
=
await
L2CrossDomainMessenger
.
MESSAGE_VERSION
()
console
.
log
(
` - MESSAGE_VERSION:
${
MESSAGE_VERSION
}
`
)
const
MIN_GAS_CALLDATA_OVERHEAD
=
await
L2CrossDomainMessenger
.
MIN_GAS_CALLDATA_OVERHEAD
()
console
.
log
(
` - MIN_GAS_CALLDATA_OVERHEAD:
${
MIN_GAS_CALLDATA_OVERHEAD
}
`
)
const
RELAY_CONSTANT_OVERHEAD
=
await
L2CrossDomainMessenger
.
RELAY_CONSTANT_OVERHEAD
()
console
.
log
(
` - RELAY_CONSTANT_OVERHEAD:
${
RELAY_CONSTANT_OVERHEAD
}
`
)
const
MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR
=
await
L2CrossDomainMessenger
.
MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR
()
console
.
log
(
` - MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR:
${
MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR
}
`
)
const
MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR
=
await
L2CrossDomainMessenger
.
MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR
()
console
.
log
(
` - MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR:
${
MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR
}
`
)
const
RELAY_CALL_OVERHEAD
=
await
L2CrossDomainMessenger
.
RELAY_CALL_OVERHEAD
()
console
.
log
(
` - RELAY_CALL_OVERHEAD:
${
RELAY_CALL_OVERHEAD
}
`
)
const
RELAY_RESERVED_GAS
=
await
L2CrossDomainMessenger
.
RELAY_RESERVED_GAS
()
console
.
log
(
` - RELAY_RESERVED_GAS:
${
RELAY_RESERVED_GAS
}
`
)
const
RELAY_GAS_CHECK_BUFFER
=
await
L2CrossDomainMessenger
.
RELAY_GAS_CHECK_BUFFER
()
console
.
log
(
` - RELAY_GAS_CHECK_BUFFER:
${
RELAY_GAS_CHECK_BUFFER
}
`
)
const
slot
=
await
signer
.
provider
.
getStorageAt
(
predeploys
.
L2CrossDomainMessenger
,
0
)
const
spacer
=
'
0x
'
+
slot
.
slice
(
26
)
console
.
log
(
` - legacy spacer:
${
spacer
}
`
)
const
initialized
=
'
0x
'
+
slot
.
slice
(
24
,
26
)
assert
(
initialized
===
'
0x01
'
)
console
.
log
(
` - initialized:
${
initialized
}
`
)
},
// GasPriceOracle
// - check version
// - check decimals
GasPriceOracle
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
GasPriceOracle
=
await
hre
.
ethers
.
getContractAt
(
'
GasPriceOracle
'
,
predeploys
.
GasPriceOracle
,
signer
)
await
assertSemver
(
GasPriceOracle
,
'
GasPriceOracle
'
,
'
1.0.1
'
)
const
decimals
=
await
GasPriceOracle
.
decimals
()
assert
(
decimals
.
eq
(
6
))
console
.
log
(
` - decimals:
${
decimals
.
toNumber
()}
`
)
await
checkProxy
(
hre
,
'
GasPriceOracle
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
GasPriceOracle
'
,
signer
.
provider
)
},
// L2StandardBridge
// - check version
L2StandardBridge
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
L2StandardBridge
=
await
hre
.
ethers
.
getContractAt
(
'
L2StandardBridge
'
,
predeploys
.
L2StandardBridge
,
signer
)
await
assertSemver
(
L2StandardBridge
,
'
L2StandardBridge
'
,
'
1.1.1
'
)
const
OTHER_BRIDGE
=
await
L2StandardBridge
.
OTHER_BRIDGE
()
assert
(
OTHER_BRIDGE
!==
hre
.
ethers
.
constants
.
AddressZero
)
yell
(
` - OTHER_BRIDGE:
${
OTHER_BRIDGE
}
`
)
const
MESSENGER
=
await
L2StandardBridge
.
MESSENGER
()
assert
(
MESSENGER
===
predeploys
.
L2CrossDomainMessenger
)
await
checkProxy
(
hre
,
'
L2StandardBridge
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
L2StandardBridge
'
,
signer
.
provider
)
},
// SequencerFeeVault
// - check version
// - check RECIPIENT
// - check l1FeeWallet (legacy)
SequencerFeeVault
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
SequencerFeeVault
=
await
hre
.
ethers
.
getContractAt
(
'
SequencerFeeVault
'
,
predeploys
.
SequencerFeeVault
,
signer
)
await
assertSemver
(
SequencerFeeVault
,
'
SequencerFeeVault
'
,
'
1.2.1
'
)
const
RECIPIENT
=
await
SequencerFeeVault
.
RECIPIENT
()
assert
(
RECIPIENT
!==
hre
.
ethers
.
constants
.
AddressZero
)
yell
(
` - RECIPIENT:
${
RECIPIENT
}
`
)
const
l1FeeWallet
=
await
SequencerFeeVault
.
l1FeeWallet
()
assert
(
l1FeeWallet
!==
hre
.
ethers
.
constants
.
AddressZero
)
console
.
log
(
` - l1FeeWallet:
${
l1FeeWallet
}
`
)
const
MIN_WITHDRAWAL_AMOUNT
=
await
SequencerFeeVault
.
MIN_WITHDRAWAL_AMOUNT
()
console
.
log
(
` - MIN_WITHDRAWAL_AMOUNT:
${
MIN_WITHDRAWAL_AMOUNT
}
`
)
const
WITHDRAWAL_NETWORK
=
await
SequencerFeeVault
.
WITHDRAWAL_NETWORK
()
assert
(
WITHDRAWAL_NETWORK
<
2
)
console
.
log
(
` - WITHDRAWAL_NETWORK:
${
WITHDRAWAL_NETWORK
}
`
)
await
checkProxy
(
hre
,
'
SequencerFeeVault
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
SequencerFeeVault
'
,
signer
.
provider
)
},
// OptimismMintableERC20Factory
// - check version
OptimismMintableERC20Factory
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
OptimismMintableERC20Factory
=
await
hre
.
ethers
.
getContractAt
(
'
OptimismMintableERC20Factory
'
,
predeploys
.
OptimismMintableERC20Factory
,
signer
)
await
assertSemver
(
OptimismMintableERC20Factory
,
'
OptimismMintableERC20Factory
'
,
'
1.1.1
'
)
const
BRIDGE
=
await
OptimismMintableERC20Factory
.
BRIDGE
()
assert
(
BRIDGE
!==
hre
.
ethers
.
constants
.
AddressZero
)
await
checkProxy
(
hre
,
'
OptimismMintableERC20Factory
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
OptimismMintableERC20Factory
'
,
signer
.
provider
)
},
// L1BlockNumber
// - check version
L1BlockNumber
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
L1BlockNumber
=
await
hre
.
ethers
.
getContractAt
(
'
L1BlockNumber
'
,
predeploys
.
L1BlockNumber
,
signer
)
await
assertSemver
(
L1BlockNumber
,
'
L1BlockNumber
'
,
'
1.0.1
'
)
await
checkProxy
(
hre
,
'
L1BlockNumber
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
L1BlockNumber
'
,
signer
.
provider
)
},
// L1Block
// - check version
L1Block
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
L1Block
=
await
hre
.
ethers
.
getContractAt
(
'
L1Block
'
,
predeploys
.
L1Block
,
signer
)
await
assertSemver
(
L1Block
,
'
L1Block
'
,
'
1.0.1
'
)
await
checkProxy
(
hre
,
'
L1Block
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
L1Block
'
,
signer
.
provider
)
},
// WETH9
// - check name
// - check symbol
// - check decimals
WETH9
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
WETH9
=
await
hre
.
ethers
.
getContractAt
(
'
WETH9
'
,
predeploys
.
WETH9
,
signer
)
const
name
=
await
WETH9
.
name
()
assert
(
name
===
'
Wrapped Ether
'
)
console
.
log
(
` - name:
${
name
}
`
)
const
symbol
=
await
WETH9
.
symbol
()
assert
(
symbol
===
'
WETH
'
)
console
.
log
(
` - symbol:
${
symbol
}
`
)
const
decimals
=
await
WETH9
.
decimals
()
assert
(
decimals
===
18
)
console
.
log
(
` - decimals:
${
decimals
}
`
)
},
// GovernanceToken
// - not behind a proxy
// - check name
// - check symbol
// - check owner
GovernanceToken
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
GovernanceToken
=
await
hre
.
ethers
.
getContractAt
(
'
GovernanceToken
'
,
predeploys
.
GovernanceToken
,
signer
)
const
name
=
await
GovernanceToken
.
name
()
assert
(
name
===
'
Optimism
'
)
console
.
log
(
` - name:
${
name
}
`
)
const
symbol
=
await
GovernanceToken
.
symbol
()
assert
(
symbol
===
'
OP
'
)
console
.
log
(
` - symbol:
${
symbol
}
`
)
const
owner
=
await
GovernanceToken
.
owner
()
yell
(
` - owner:
${
owner
}
`
)
const
totalSupply
=
await
GovernanceToken
.
totalSupply
()
console
.
log
(
` - totalSupply:
${
totalSupply
}
`
)
await
checkProxy
(
hre
,
'
GovernanceToken
'
,
signer
.
provider
)
// No proxy at this address, don't call assertProxy
},
// L2ERC721Bridge
// - check version
L2ERC721Bridge
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
L2ERC721Bridge
=
await
hre
.
ethers
.
getContractAt
(
'
L2ERC721Bridge
'
,
predeploys
.
L2ERC721Bridge
,
signer
)
await
assertSemver
(
L2ERC721Bridge
,
'
L2ERC721Bridge
'
,
'
1.1.1
'
)
const
MESSENGER
=
await
L2ERC721Bridge
.
MESSENGER
()
assert
(
MESSENGER
!==
hre
.
ethers
.
constants
.
AddressZero
)
console
.
log
(
` - MESSENGER:
${
MESSENGER
}
`
)
const
OTHER_BRIDGE
=
await
L2ERC721Bridge
.
OTHER_BRIDGE
()
assert
(
OTHER_BRIDGE
!==
hre
.
ethers
.
constants
.
AddressZero
)
yell
(
` - OTHER_BRIDGE:
${
OTHER_BRIDGE
}
`
)
await
checkProxy
(
hre
,
'
L2ERC721Bridge
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
L2ERC721Bridge
'
,
signer
.
provider
)
},
// OptimismMintableERC721Factory
// - check version
OptimismMintableERC721Factory
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
OptimismMintableERC721Factory
=
await
hre
.
ethers
.
getContractAt
(
'
OptimismMintableERC721Factory
'
,
predeploys
.
OptimismMintableERC721Factory
,
signer
)
await
assertSemver
(
OptimismMintableERC721Factory
,
'
OptimismMintableERC721Factory
'
,
'
1.2.1
'
)
const
BRIDGE
=
await
OptimismMintableERC721Factory
.
BRIDGE
()
assert
(
BRIDGE
!==
hre
.
ethers
.
constants
.
AddressZero
)
console
.
log
(
` - BRIDGE:
${
BRIDGE
}
`
)
const
REMOTE_CHAIN_ID
=
await
OptimismMintableERC721Factory
.
REMOTE_CHAIN_ID
()
assert
(
REMOTE_CHAIN_ID
!==
0
)
console
.
log
(
` - REMOTE_CHAIN_ID:
${
REMOTE_CHAIN_ID
}
`
)
await
checkProxy
(
hre
,
'
OptimismMintableERC721Factory
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
OptimismMintableERC721Factory
'
,
signer
.
provider
)
},
// ProxyAdmin
// - check owner
ProxyAdmin
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
ProxyAdmin
=
await
hre
.
ethers
.
getContractAt
(
'
ProxyAdmin
'
,
predeploys
.
ProxyAdmin
,
signer
)
const
owner
=
await
ProxyAdmin
.
owner
()
assert
(
owner
!==
hre
.
ethers
.
constants
.
AddressZero
)
yell
(
` - owner:
${
owner
}
`
)
const
addressManager
=
await
ProxyAdmin
.
addressManager
()
console
.
log
(
` - addressManager:
${
addressManager
}
`
)
await
checkProxy
(
hre
,
'
ProxyAdmin
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
ProxyAdmin
'
,
signer
.
provider
)
},
// BaseFeeVault
// - check version
// - check MIN_WITHDRAWAL_AMOUNT
// - check RECIPIENT
BaseFeeVault
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
BaseFeeVault
=
await
hre
.
ethers
.
getContractAt
(
'
BaseFeeVault
'
,
predeploys
.
BaseFeeVault
,
signer
)
await
assertSemver
(
BaseFeeVault
,
'
BaseFeeVault
'
,
'
1.2.1
'
)
const
MIN_WITHDRAWAL_AMOUNT
=
await
BaseFeeVault
.
MIN_WITHDRAWAL_AMOUNT
()
console
.
log
(
` - MIN_WITHDRAWAL_AMOUNT:
${
MIN_WITHDRAWAL_AMOUNT
}
`
)
const
RECIPIENT
=
await
BaseFeeVault
.
RECIPIENT
()
assert
(
RECIPIENT
!==
hre
.
ethers
.
constants
.
AddressZero
)
yell
(
` - RECIPIENT:
${
RECIPIENT
}
`
)
const
WITHDRAWAL_NETWORK
=
await
BaseFeeVault
.
WITHDRAWAL_NETWORK
()
assert
(
WITHDRAWAL_NETWORK
<
2
)
console
.
log
(
` - WITHDRAWAL_NETWORK:
${
WITHDRAWAL_NETWORK
}
`
)
await
checkProxy
(
hre
,
'
BaseFeeVault
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
BaseFeeVault
'
,
signer
.
provider
)
},
// L1FeeVault
// - check version
// - check MIN_WITHDRAWAL_AMOUNT
// - check RECIPIENT
L1FeeVault
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
L1FeeVault
=
await
hre
.
ethers
.
getContractAt
(
'
L1FeeVault
'
,
predeploys
.
L1FeeVault
,
signer
)
await
assertSemver
(
L1FeeVault
,
'
L1FeeVault
'
,
'
1.2.1
'
)
const
MIN_WITHDRAWAL_AMOUNT
=
await
L1FeeVault
.
MIN_WITHDRAWAL_AMOUNT
()
console
.
log
(
` - MIN_WITHDRAWAL_AMOUNT:
${
MIN_WITHDRAWAL_AMOUNT
}
`
)
const
RECIPIENT
=
await
L1FeeVault
.
RECIPIENT
()
assert
(
RECIPIENT
!==
hre
.
ethers
.
constants
.
AddressZero
)
yell
(
` - RECIPIENT:
${
RECIPIENT
}
`
)
const
WITHDRAWAL_NETWORK
=
await
L1FeeVault
.
WITHDRAWAL_NETWORK
()
assert
(
WITHDRAWAL_NETWORK
<
2
)
console
.
log
(
` - WITHDRAWAL_NETWORK:
${
WITHDRAWAL_NETWORK
}
`
)
await
checkProxy
(
hre
,
'
L1FeeVault
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
L1FeeVault
'
,
signer
.
provider
)
},
// L2ToL1MessagePasser
// - check version
L2ToL1MessagePasser
:
async
(
hre
:
HardhatRuntimeEnvironment
,
signer
:
Signer
)
=>
{
const
L2ToL1MessagePasser
=
await
hre
.
ethers
.
getContractAt
(
'
L2ToL1MessagePasser
'
,
predeploys
.
L2ToL1MessagePasser
,
signer
)
await
assertSemver
(
L2ToL1MessagePasser
,
'
L2ToL1MessagePasser
'
,
'
1.0.1
'
)
const
MESSAGE_VERSION
=
await
L2ToL1MessagePasser
.
MESSAGE_VERSION
()
console
.
log
(
` - MESSAGE_VERSION:
${
MESSAGE_VERSION
}
`
)
const
messageNonce
=
await
L2ToL1MessagePasser
.
messageNonce
()
console
.
log
(
` - messageNonce:
${
messageNonce
}
`
)
await
checkProxy
(
hre
,
'
L2ToL1MessagePasser
'
,
signer
.
provider
)
await
assertProxy
(
hre
,
'
L2ToL1MessagePasser
'
,
signer
.
provider
)
},
}
task
(
'
check-l2
'
,
'
Checks a freshly migrated L2 system for correct migration
'
)
.
addOptionalParam
(
'
l1RpcUrl
'
,
'
L1 RPC URL of node
'
,
''
,
types
.
string
)
.
addOptionalParam
(
'
l2RpcUrl
'
,
'
L2 RPC URL of node
'
,
''
,
types
.
string
)
.
addOptionalParam
(
'
chainId
'
,
'
Expected chain id
'
,
0
,
types
.
int
)
.
addOptionalParam
(
'
l2OutputOracleAddress
'
,
'
Address of the L2OutputOracle oracle
'
,
''
,
types
.
string
)
.
addOptionalParam
(
'
skipPredeployCheck
'
,
'
Skip long check
'
,
false
,
types
.
boolean
)
.
setAction
(
async
(
args
,
hre
:
HardhatRuntimeEnvironment
)
=>
{
yell
(
'
Manually check values wrapped in !!!!
'
)
console
.
log
()
let
signer
:
Signer
=
hre
.
ethers
.
provider
.
getSigner
()
if
(
args
.
l2RpcUrl
!==
''
)
{
console
.
log
(
'
Using CLI URL for provider instead of hardhat network
'
)
const
provider
=
new
hre
.
ethers
.
providers
.
JsonRpcBatchProvider
(
args
.
l2RpcUrl
)
signer
=
Wallet
.
createRandom
().
connect
(
provider
)
}
if
(
args
.
chainId
!==
0
)
{
const
chainId
=
await
signer
.
getChainId
()
if
(
chainId
!==
args
.
chainId
)
{
throw
new
Error
(
`Unexpected Chain ID. Got
${
chainId
}
, expected
${
args
.
chainId
}
`
)
}
console
.
log
(
`Verified Chain ID:
${
chainId
}
`
)
}
else
{
console
.
log
(
`Skipping Chain ID validation...`
)
}
// Ensure that all the predeploys exist, including the not
// currently configured ones
if
(
!
args
.
skipPredeployCheck
)
{
await
checkPredeploys
(
hre
,
signer
.
provider
)
}
await
checkGenesisMagic
(
hre
,
signer
.
provider
,
args
)
console
.
log
()
// Check the currently configured predeploys
for
(
const
[
name
,
fn
]
of
Object
.
entries
(
check
))
{
const
address
=
predeploys
[
name
]
console
.
log
(
`
${
name
}
:
${
address
}
`
)
await
fn
(
hre
,
signer
)
}
})
packages/contracts-bedrock/tasks/index.ts
View file @
dc3922cf
import
'
./solidity
'
import
'
./check-l2
'
import
'
./generate-deploy-config
'
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment