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
d7978cfc
Unverified
Commit
d7978cfc
authored
Oct 03, 2021
by
Kelvin Fichter
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: cleanup deployment process
parent
2af70190
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
224 additions
and
206 deletions
+224
-206
dull-shirts-develop.md
.changeset/dull-shirts-develop.md
+5
-0
000-Lib_AddressManager.deploy.ts
packages/contracts/deploy/000-Lib_AddressManager.deploy.ts
+8
-1
006-OVM_BondManager.deploy.ts
packages/contracts/deploy/006-OVM_BondManager.deploy.ts
+8
-17
007-OVM_L1CrossDomainMessenger.deploy.ts
...contracts/deploy/007-OVM_L1CrossDomainMessenger.deploy.ts
+26
-41
008-Proxy__OVM_L1CrossDomainMessenger.deploy.ts
...ts/deploy/008-Proxy__OVM_L1CrossDomainMessenger.deploy.ts
+23
-43
009-Proxy__OVM_L1StandardBridge.deploy.ts
...ontracts/deploy/009-Proxy__OVM_L1StandardBridge.deploy.ts
+87
-75
010-finalize.ts
packages/contracts/deploy/010-finalize.ts
+12
-15
hardhat-deploy-ethers.ts
packages/contracts/src/hardhat-deploy-ethers.ts
+42
-13
hex-strings.ts
packages/core-utils/src/common/hex-strings.ts
+13
-1
No files found.
.changeset/dull-shirts-develop.md
0 → 100644
View file @
d7978cfc
---
'
@eth-optimism/contracts'
:
patch
---
Cleans up the contract deployment process
packages/contracts/deploy/000-Lib_AddressManager.deploy.ts
View file @
d7978cfc
...
@@ -15,18 +15,25 @@ const deployFn: DeployFunction = async (hre) => {
...
@@ -15,18 +15,25 @@ const deployFn: DeployFunction = async (hre) => {
log
:
true
,
log
:
true
,
})
})
// L2CrossDomainMessenger is the address of the predeploy on L2. We can refactor off-chain
// services such that we can remove the need to set this address, but for now it's easier
// to simply keep setting the address.
await
registerAddress
({
await
registerAddress
({
hre
,
hre
,
name
:
'
L2CrossDomainMessenger
'
,
name
:
'
L2CrossDomainMessenger
'
,
address
:
predeploys
.
L2CrossDomainMessenger
,
address
:
predeploys
.
L2CrossDomainMessenger
,
})
})
// OVM_Sequencer is the address allowed to submit "Sequencer" blocks to the
// CanonicalTransactionChain.
await
registerAddress
({
await
registerAddress
({
hre
,
hre
,
name
:
'
OVM_Sequencer
'
,
name
:
'
OVM_Sequencer
'
,
address
:
(
hre
as
any
).
deployConfig
.
ovmSequencerAddress
,
address
:
(
hre
as
any
).
deployConfig
.
ovmSequencerAddress
,
})
})
// OVM_Proposer is the address allowed to submit state roots (transaction results) to the
// StateCommitmentChain.
await
registerAddress
({
await
registerAddress
({
hre
,
hre
,
name
:
'
OVM_Proposer
'
,
name
:
'
OVM_Proposer
'
,
...
@@ -34,6 +41,6 @@ const deployFn: DeployFunction = async (hre) => {
...
@@ -34,6 +41,6 @@ const deployFn: DeployFunction = async (hre) => {
})
})
}
}
deployFn
.
tags
=
[
'
Lib_AddressManager
'
,
'
required
'
]
deployFn
.
tags
=
[
'
Lib_AddressManager
'
]
export
default
deployFn
export
default
deployFn
packages/contracts/deploy/006-OVM_BondManager.deploy.ts
View file @
d7978cfc
...
@@ -2,31 +2,22 @@
...
@@ -2,31 +2,22 @@
import
{
DeployFunction
}
from
'
hardhat-deploy/dist/types
'
import
{
DeployFunction
}
from
'
hardhat-deploy/dist/types
'
/* Imports: Internal */
/* Imports: Internal */
import
{
getDeployedContract
}
from
'
../src/hardhat-deploy-ethers
'
import
{
deployAndRegister
,
getDeployedContract
,
}
from
'
../src/hardhat-deploy-ethers
'
const
deployFn
:
DeployFunction
=
async
(
hre
)
=>
{
const
deployFn
:
DeployFunction
=
async
(
hre
)
=>
{
const
{
deploy
}
=
hre
.
deployments
const
{
deployer
}
=
await
hre
.
getNamedAccounts
()
const
Lib_AddressManager
=
await
getDeployedContract
(
const
Lib_AddressManager
=
await
getDeployedContract
(
hre
,
hre
,
'
Lib_AddressManager
'
,
'
Lib_AddressManager
'
{
signerOrProvider
:
deployer
,
}
)
)
const
result
=
await
deploy
(
'
BondManager
'
,
{
await
deployAndRegister
({
from
:
deployer
,
hre
,
name
:
'
BondManager
'
,
args
:
[
Lib_AddressManager
.
address
],
args
:
[
Lib_AddressManager
.
address
],
log
:
true
,
})
})
if
(
!
result
.
newlyDeployed
)
{
return
}
await
Lib_AddressManager
.
setAddress
(
'
BondManager
'
,
result
.
address
)
}
}
deployFn
.
dependencies
=
[
'
Lib_AddressManager
'
]
deployFn
.
dependencies
=
[
'
Lib_AddressManager
'
]
...
...
packages/contracts/deploy/007-OVM_L1CrossDomainMessenger.deploy.ts
View file @
d7978cfc
/* Imports: External */
/* Imports: External */
import
{
DeployFunction
}
from
'
hardhat-deploy/dist/types
'
import
{
DeployFunction
}
from
'
hardhat-deploy/dist/types
'
import
{
hexStringEquals
}
from
'
@eth-optimism/core-utils
'
/* Imports: Internal */
/* Imports: Internal */
import
{
getDeployedContract
}
from
'
../src/hardhat-deploy-ethers
'
import
{
getDeployedContract
,
deployAndRegister
,
waitUntilTrue
,
}
from
'
../src/hardhat-deploy-ethers
'
const
deployFn
:
DeployFunction
=
async
(
hre
)
=>
{
const
deployFn
:
DeployFunction
=
async
(
hre
)
=>
{
const
{
deploy
}
=
hre
.
deployments
const
{
deployer
}
=
await
hre
.
getNamedAccounts
()
const
Lib_AddressManager
=
await
getDeployedContract
(
const
Lib_AddressManager
=
await
getDeployedContract
(
hre
,
hre
,
'
Lib_AddressManager
'
,
'
Lib_AddressManager
'
{
signerOrProvider
:
deployer
,
}
)
)
const
result
=
await
deploy
(
'
L1CrossDomainMessenger
'
,
{
await
deployAndRegister
({
from
:
deployer
,
hre
,
name
:
'
L1CrossDomainMessenger
'
,
args
:
[],
args
:
[],
log
:
true
,
postDeployAction
:
async
(
contract
)
=>
{
// Theoretically it's not necessary to initialize this contract since it sits behind
// a proxy. However, it's best practice to initialize it anyway just in case there's
// some unknown security hole. It also prevents another user from appearing like an
// official address because it managed to call the initialization function.
console
.
log
(
`Initializing L1CrossDomainMessenger...`
)
await
contract
.
initialize
(
Lib_AddressManager
.
address
)
console
.
log
(
`Checking that contract was correctly initialized...`
)
await
waitUntilTrue
(
async
()
=>
{
return
hexStringEquals
(
await
contract
.
libAddressManager
(),
Lib_AddressManager
.
address
)
})
},
})
})
if
(
!
result
.
newlyDeployed
)
{
return
}
const
L1CrossDomainMessenger
=
await
getDeployedContract
(
hre
,
'
L1CrossDomainMessenger
'
,
{
signerOrProvider
:
deployer
,
}
)
// NOTE: this initialization is *not* technically required (we only need to initialize the proxy)
// but it feels safer to initialize this anyway. Otherwise someone else could come along and
// initialize this.
await
L1CrossDomainMessenger
.
initialize
(
Lib_AddressManager
.
address
)
const
libAddressManager
=
await
L1CrossDomainMessenger
.
libAddressManager
()
if
(
libAddressManager
!==
Lib_AddressManager
.
address
)
{
throw
new
Error
(
`\n**FATAL ERROR. THIS SHOULD NEVER HAPPEN. CHECK YOUR DEPLOYMENT.**:\n`
+
`L1CrossDomainMessenger could not be succesfully initialized.\n`
+
`Attempted to set Lib_AddressManager to:
${
Lib_AddressManager
.
address
}
\n`
+
`Actual address after initialization:
${
libAddressManager
}
\n`
+
`This could indicate a compromised deployment.`
)
}
await
Lib_AddressManager
.
setAddress
(
'
L1CrossDomainMessenger
'
,
result
.
address
)
}
}
deployFn
.
dependencies
=
[
'
Lib_AddressManager
'
]
deployFn
.
dependencies
=
[
'
Lib_AddressManager
'
]
...
...
packages/contracts/deploy/008-Proxy__OVM_L1CrossDomainMessenger.deploy.ts
View file @
d7978cfc
/* Imports: External */
/* Imports: External */
import
{
DeployFunction
}
from
'
hardhat-deploy/dist/types
'
import
{
DeployFunction
}
from
'
hardhat-deploy/dist/types
'
import
{
hexStringEquals
}
from
'
@eth-optimism/core-utils
'
/* Imports: Internal */
/* Imports: Internal */
import
{
getDeployedContract
}
from
'
../src/hardhat-deploy-ethers
'
import
{
getDeployedContract
,
deployAndRegister
,
waitUntilTrue
,
}
from
'
../src/hardhat-deploy-ethers
'
const
deployFn
:
DeployFunction
=
async
(
hre
)
=>
{
const
deployFn
:
DeployFunction
=
async
(
hre
)
=>
{
const
{
deploy
}
=
hre
.
deployments
const
{
deployer
}
=
await
hre
.
getNamedAccounts
()
const
Lib_AddressManager
=
await
getDeployedContract
(
const
Lib_AddressManager
=
await
getDeployedContract
(
hre
,
hre
,
'
Lib_AddressManager
'
,
'
Lib_AddressManager
'
{
signerOrProvider
:
deployer
,
}
)
)
const
result
=
await
deploy
(
'
Proxy__L1CrossDomainMessenger
'
,
{
await
deployAndRegister
({
hre
,
name
:
'
Proxy__L1CrossDomainMessenger
'
,
contract
:
'
Lib_ResolvedDelegateProxy
'
,
contract
:
'
Lib_ResolvedDelegateProxy
'
,
from
:
deployer
,
iface
:
'
L1CrossDomainMessenger
'
,
args
:
[
Lib_AddressManager
.
address
,
'
L1CrossDomainMessenger
'
],
args
:
[
Lib_AddressManager
.
address
,
'
L1CrossDomainMessenger
'
],
log
:
true
,
postDeployAction
:
async
(
contract
)
=>
{
console
.
log
(
`Initializing Proxy__L1CrossDomainMessenger...`
)
await
contract
.
initialize
(
Lib_AddressManager
.
address
)
console
.
log
(
`Checking that contract was correctly initialized...`
)
await
waitUntilTrue
(
async
()
=>
{
return
hexStringEquals
(
await
contract
.
libAddressManager
(),
Lib_AddressManager
.
address
)
})
},
})
})
if
(
!
result
.
newlyDeployed
)
{
return
}
const
Proxy__L1CrossDomainMessenger
=
await
getDeployedContract
(
hre
,
'
Proxy__L1CrossDomainMessenger
'
,
{
signerOrProvider
:
deployer
,
iface
:
'
L1CrossDomainMessenger
'
,
}
)
await
Proxy__L1CrossDomainMessenger
.
initialize
(
Lib_AddressManager
.
address
)
const
libAddressManager
=
await
Proxy__L1CrossDomainMessenger
.
libAddressManager
()
if
(
libAddressManager
!==
Lib_AddressManager
.
address
)
{
throw
new
Error
(
`\n**FATAL ERROR. THIS SHOULD NEVER HAPPEN. CHECK YOUR DEPLOYMENT.**:\n`
+
`Proxy__L1CrossDomainMessenger could not be succesfully initialized.\n`
+
`Attempted to set Lib_AddressManager to:
${
Lib_AddressManager
.
address
}
\n`
+
`Actual address after initialization:
${
libAddressManager
}
\n`
+
`This could indicate a compromised deployment.`
)
}
await
Lib_AddressManager
.
setAddress
(
'
Proxy__L1CrossDomainMessenger
'
,
result
.
address
)
}
}
deployFn
.
dependencies
=
[
'
Lib_AddressManager
'
,
'
L1CrossDomainMessenger
'
]
deployFn
.
dependencies
=
[
'
Lib_AddressManager
'
,
'
L1CrossDomainMessenger
'
]
...
...
packages/contracts/deploy/009-Proxy__OVM_L1StandardBridge.deploy.ts
View file @
d7978cfc
/* Imports: External */
/* Imports: External */
import
{
DeployFunction
}
from
'
hardhat-deploy/dist/types
'
import
{
DeployFunction
}
from
'
hardhat-deploy/dist/types
'
import
{
ethers
}
from
'
ethers
'
import
{
hexStringEquals
}
from
'
@eth-optimism/core-utils
'
/* Imports: Internal */
/* Imports: Internal */
import
{
getDeployedContract
}
from
'
../src/hardhat-deploy-ethers
'
import
{
predeploys
}
from
'
../src/predeploys
'
import
{
predeploys
}
from
'
../src/predeploys
'
import
{
NON_ZERO_ADDRESS
}
from
'
../test/helpers/constants
'
import
{
import
{
getContractFactory
}
from
'
../src/contract-defs
'
getContractInterface
,
getContractDefinition
,
import
l1StandardBridgeJson
from
'
../artifacts/contracts/L1/messaging/L1StandardBridge.sol/L1StandardBridge.json
'
}
from
'
../src/contract-defs
'
import
{
getDeployedContract
,
deployAndRegister
,
waitUntilTrue
,
}
from
'
../src/hardhat-deploy-ethers
'
const
deployFn
:
DeployFunction
=
async
(
hre
)
=>
{
const
deployFn
:
DeployFunction
=
async
(
hre
)
=>
{
const
{
deploy
}
=
hre
.
deployments
const
{
deployer
}
=
await
hre
.
getNamedAccounts
()
const
{
deployer
}
=
await
hre
.
getNamedAccounts
()
const
Lib_AddressManager
=
await
getDeployedContract
(
const
Lib_AddressManager
=
await
getDeployedContract
(
hre
,
hre
,
'
Lib_AddressManager
'
,
'
Lib_AddressManager
'
{
signerOrProvider
:
deployer
,
}
)
)
const
result
=
await
deploy
(
'
Proxy__L1StandardBridge
'
,
{
await
deployAndRegister
({
hre
,
name
:
'
Proxy__L1StandardBridge
'
,
contract
:
'
L1ChugSplashProxy
'
,
contract
:
'
L1ChugSplashProxy
'
,
from
:
deployer
,
iface
:
'
L1StandardBridge
'
,
args
:
[
deployer
],
args
:
[
deployer
],
log
:
true
,
postDeployAction
:
async
(
contract
)
=>
{
})
// Because of the `iface` parameter supplied to the deployment function above, the `contract`
// variable that we here will have the interface of the L1StandardBridge contract. However,
// we also need to interact with the contract as if it were a L1ChugSplashProxy contract so
// we instantiate a new ethers.Contract object with the same address and signer but with the
// L1ChugSplashProxy interface.
const
proxy
=
new
ethers
.
Contract
(
contract
.
address
,
getContractInterface
(
'
L1ChugSplashProxy
'
),
contract
.
signer
)
if
(
!
result
.
newlyDeployed
)
{
// First we need to set the correct implementation code. We'll set the code and then check
return
// that the code was indeed correctly set.
}
const
bridgeArtifact
=
getContractDefinition
(
'
L1StandardBridge
'
)
const
bridgeCode
=
bridgeArtifact
.
deployedBytecode
// Create a contract object at the Proxy address with the proxy interface.
console
.
log
(
`Setting bridge code...`
)
const
Proxy__WithChugSplashInterface
=
await
getDeployedContract
(
await
proxy
.
setCode
(
bridgeCode
)
hre
,
'
Proxy__L1StandardBridge
'
,
{
signerOrProvider
:
deployer
,
iface
:
'
L1ChugSplashProxy
'
,
}
)
// Create a contract object at the Proxy address with the brige implementation interface.
console
.
log
(
`Confirming that bridge code is correct...`
)
const
Proxy__WithBridgeInterface
=
await
getDeployedContract
(
await
waitUntilTrue
(
async
()
=>
{
hre
,
const
implementation
=
await
proxy
.
callStatic
.
getImplementation
()
'
Proxy__L1StandardBridge
'
,
return
(
{
!
hexStringEquals
(
implementation
,
ethers
.
constants
.
AddressZero
)
&&
signerOrProvider
:
deployer
,
hexStringEquals
(
iface
:
'
L1StandardBridge
'
,
await
contract
.
provider
.
getCode
(
implementation
),
}
bridgeCode
)
)
)
})
// Set the implementation code
// Next we need to set the `messenger` address by executing a setStorage operation. We'll
const
bridgeCode
=
l1StandardBridgeJson
.
deployedBytecode
// check that this operation was correctly executed by calling `messenger()` and checking
await
Proxy__WithChugSplashInterface
.
setCode
(
bridgeCode
)
// that the result matches the value we initialized.
const
l1CrossDomainMessengerAddress
=
await
Lib_AddressManager
.
getAddress
(
'
Proxy__L1CrossDomainMessenger
'
)
// Set slot 0 to the L1 Messenger Address
console
.
log
(
`Setting messenger address...`
)
const
l1MessengerAddress
=
await
Lib_AddressManager
.
getAddress
(
await
proxy
.
setStorage
(
'
Proxy__L1CrossDomainMessenger
'
ethers
.
utils
.
hexZeroPad
(
'
0x00
'
,
32
),
)
ethers
.
utils
.
hexZeroPad
(
l1CrossDomainMessengerAddress
,
32
)
await
Proxy__WithChugSplashInterface
.
setStorage
(
)
hre
.
ethers
.
constants
.
HashZero
,
hre
.
ethers
.
utils
.
hexZeroPad
(
l1MessengerAddress
,
32
)
)
// Verify that the slot was set correctly
const
l1MessengerStored
=
await
Proxy__WithBridgeInterface
.
callStatic
.
messenger
()
console
.
log
(
'
l1MessengerStored:
'
,
l1MessengerStored
)
if
(
l1MessengerStored
!==
l1MessengerAddress
)
{
throw
new
Error
(
'
L1 messenger address was not correctly set, check the key value used in setStorage
'
)
}
// Set Slot 1 to the L2 Standard Bridge Address
console
.
log
(
`Confirming that messenger address was correctly set...`
)
await
Proxy__WithChugSplashInterface
.
setStorage
(
await
waitUntilTrue
(
async
()
=>
{
hre
.
ethers
.
utils
.
hexZeroPad
(
'
0x01
'
,
32
),
return
hexStringEquals
(
hre
.
ethers
.
utils
.
hexZeroPad
(
predeploys
.
L2StandardBridge
,
32
)
await
contract
.
messenger
(),
)
l1CrossDomainMessengerAddress
// Verify that the slot was set correctly
)
const
l2TokenBridgeStored
=
})
await
Proxy__WithBridgeInterface
.
callStatic
.
l2TokenBridge
()
console
.
log
(
'
l2TokenBridgeStored:
'
,
l2TokenBridgeStored
)
if
(
l2TokenBridgeStored
!==
predeploys
.
L2StandardBridge
)
{
throw
new
Error
(
'
L2 bridge address was not correctly set, check the key value used in setStorage
'
)
}
// transfer ownership to Address Manager owner
// Now we set the bridge address in the same manner as the messenger address.
const
addressManagerOwner
=
Lib_AddressManager
.
callStatic
.
owner
()
console
.
log
(
`Setting l2 bridge address...`
)
await
Proxy__WithChugSplashInterface
.
setOwner
(
addressManagerOwner
)
await
proxy
.
setStorage
(
ethers
.
utils
.
hexZeroPad
(
'
0x01
'
,
32
),
ethers
.
utils
.
hexZeroPad
(
predeploys
.
L2StandardBridge
,
32
)
)
// Todo: remove this after adding chugsplash proxy
console
.
log
(
`Confirming that l2 bridge address was correctly set...`
)
await
Lib_AddressManager
.
setAddress
(
'
Proxy__L1StandardBridge
'
,
result
.
address
)
await
waitUntilTrue
(
async
()
=>
{
return
hexStringEquals
(
await
contract
.
l2TokenBridge
(),
predeploys
.
L2StandardBridge
)
})
// Finally we transfer ownership of the proxy to the ovmAddressManagerOwner address.
console
.
log
(
`Setting owner address...`
)
const
owner
=
(
hre
as
any
).
deployConfig
.
ovmAddressManagerOwner
await
proxy
.
setOwner
(
owner
)
console
.
log
(
`Confirming that owner address was correctly set...`
)
await
waitUntilTrue
(
async
()
=>
{
return
hexStringEquals
(
await
proxy
.
callStatic
.
getOwner
(),
owner
)
})
},
})
}
}
deployFn
.
dependencies
=
[
'
Lib_AddressManager
'
,
'
L1StandardBridge
'
]
deployFn
.
dependencies
=
[
'
Lib_AddressManager
'
,
'
L1StandardBridge
'
]
...
...
packages/contracts/deploy/010-finalize.ts
View file @
d7978cfc
/* Imports: External */
/* Imports: External */
import
{
DeployFunction
}
from
'
hardhat-deploy/dist/types
'
import
{
DeployFunction
}
from
'
hardhat-deploy/dist/types
'
import
{
hexStringEquals
}
from
'
@eth-optimism/core-utils
'
/* Imports: Internal */
/* Imports: Internal */
import
{
getDeployedContract
}
from
'
../src/hardhat-deploy-ethers
'
import
{
getDeployedContract
,
waitUntilTrue
,
}
from
'
../src/hardhat-deploy-ethers
'
const
deployFn
:
DeployFunction
=
async
(
hre
)
=>
{
const
deployFn
:
DeployFunction
=
async
(
hre
)
=>
{
const
{
deployer
}
=
await
hre
.
getNamedAccounts
()
const
{
deployer
}
=
await
hre
.
getNamedAccounts
()
...
@@ -16,7 +20,7 @@ const deployFn: DeployFunction = async (hre) => {
...
@@ -16,7 +20,7 @@ const deployFn: DeployFunction = async (hre) => {
const
owner
=
(
hre
as
any
).
deployConfig
.
ovmAddressManagerOwner
const
owner
=
(
hre
as
any
).
deployConfig
.
ovmAddressManagerOwner
const
remoteOwner
=
await
Lib_AddressManager
.
owner
()
const
remoteOwner
=
await
Lib_AddressManager
.
owner
()
if
(
remoteOwner
===
owner
)
{
if
(
hexStringEquals
(
owner
,
remoteOwner
)
)
{
console
.
log
(
console
.
log
(
`✓ Not changing owner of Lib_AddressManager because it's already correctly set`
`✓ Not changing owner of Lib_AddressManager because it's already correctly set`
)
)
...
@@ -24,19 +28,12 @@ const deployFn: DeployFunction = async (hre) => {
...
@@ -24,19 +28,12 @@ const deployFn: DeployFunction = async (hre) => {
}
}
console
.
log
(
`Transferring ownership of Lib_AddressManager to
${
owner
}
...`
)
console
.
log
(
`Transferring ownership of Lib_AddressManager to
${
owner
}
...`
)
const
tx
=
await
Lib_AddressManager
.
transferOwnership
(
owner
)
await
Lib_AddressManager
.
transferOwnership
(
owner
)
await
tx
.
wait
()
console
.
log
(
`Confirming transfer was successful...`
)
const
newRemoteOwner
=
await
Lib_AddressManager
.
owner
()
await
waitUntilTrue
(
async
()
=>
{
if
(
newRemoteOwner
!==
owner
)
{
return
hexStringEquals
(
await
Lib_AddressManager
.
owner
(),
owner
)
throw
new
Error
(
})
`\n**FATAL ERROR. THIS SHOULD NEVER HAPPEN. CHECK YOUR DEPLOYMENT.**:\n`
+
`Could not transfer ownership of Lib_AddressManager.\n`
+
`Attempted to set owner of Lib_AddressManager to:
${
owner
}
\n`
+
`Actual owner after transaction:
${
newRemoteOwner
}
\n`
+
`This could indicate a compromised deployment.`
)
}
console
.
log
(
`✓ Set owner of Lib_AddressManager to:
${
owner
}
`
)
console
.
log
(
`✓ Set owner of Lib_AddressManager to:
${
owner
}
`
)
}
}
...
...
packages/contracts/src/hardhat-deploy-ethers.ts
View file @
d7978cfc
...
@@ -2,6 +2,27 @@
...
@@ -2,6 +2,27 @@
import
{
Contract
}
from
'
ethers
'
import
{
Contract
}
from
'
ethers
'
import
{
Provider
}
from
'
@ethersproject/abstract-provider
'
import
{
Provider
}
from
'
@ethersproject/abstract-provider
'
import
{
Signer
}
from
'
@ethersproject/abstract-signer
'
import
{
Signer
}
from
'
@ethersproject/abstract-signer
'
import
{
sleep
,
hexStringEquals
}
from
'
@eth-optimism/core-utils
'
export
const
waitUntilTrue
=
async
(
check
:
()
=>
Promise
<
boolean
>
,
opts
:
{
retries
?:
number
delay
?:
number
}
=
{}
)
=>
{
opts
.
retries
=
opts
.
retries
||
10
opts
.
delay
=
opts
.
delay
||
5000
let
retries
=
0
while
(
!
(
await
check
()))
{
if
(
retries
>
opts
.
retries
)
{
throw
new
Error
(
`check failed after
${
opts
.
retries
}
attempts`
)
}
retries
++
await
sleep
(
opts
.
delay
)
}
}
export
const
registerAddress
=
async
({
export
const
registerAddress
=
async
({
hre
,
hre
,
...
@@ -27,19 +48,12 @@ export const registerAddress = async ({
...
@@ -27,19 +48,12 @@ export const registerAddress = async ({
}
}
console
.
log
(
`Registering address for
${
name
}
to
${
address
}
...`
)
console
.
log
(
`Registering address for
${
name
}
to
${
address
}
...`
)
const
tx
=
await
Lib_AddressManager
.
setAddress
(
name
,
address
)
await
Lib_AddressManager
.
setAddress
(
name
,
address
)
await
tx
.
wait
()
console
.
log
(
`Waiting for registration to reflect on-chain...`
)
const
remoteAddress
=
await
Lib_AddressManager
.
getAddress
(
name
)
await
waitUntilTrue
(
async
()
=>
{
if
(
remoteAddress
!==
address
)
{
return
hexStringEquals
(
await
Lib_AddressManager
.
getAddress
(
name
),
address
)
throw
new
Error
(
})
`\n**FATAL ERROR. THIS SHOULD NEVER HAPPEN. CHECK YOUR DEPLOYMENT.**:\n`
+
`Call to Lib_AddressManager.setAddress(
${
name
}
) was unsuccessful.\n`
+
`Attempted to set address to:
${
address
}
\n`
+
`Actual address was set to:
${
remoteAddress
}
\n`
+
`This could indicate a compromised deployment.`
)
}
console
.
log
(
`✓ Registered address for
${
name
}
`
)
console
.
log
(
`✓ Registered address for
${
name
}
`
)
}
}
...
@@ -49,11 +63,15 @@ export const deployAndRegister = async ({
...
@@ -49,11 +63,15 @@ export const deployAndRegister = async ({
name
,
name
,
args
,
args
,
contract
,
contract
,
iface
,
postDeployAction
,
}:
{
}:
{
hre
:
any
hre
:
any
name
:
string
name
:
string
args
:
any
[]
args
:
any
[]
contract
?:
string
contract
?:
string
iface
?:
string
postDeployAction
?:
(
contract
:
Contract
)
=>
Promise
<
void
>
})
=>
{
})
=>
{
const
{
deploy
}
=
hre
.
deployments
const
{
deploy
}
=
hre
.
deployments
const
{
deployer
}
=
await
hre
.
getNamedAccounts
()
const
{
deployer
}
=
await
hre
.
getNamedAccounts
()
...
@@ -68,6 +86,17 @@ export const deployAndRegister = async ({
...
@@ -68,6 +86,17 @@ export const deployAndRegister = async ({
await
hre
.
ethers
.
provider
.
waitForTransaction
(
result
.
transactionHash
)
await
hre
.
ethers
.
provider
.
waitForTransaction
(
result
.
transactionHash
)
if
(
result
.
newlyDeployed
)
{
if
(
result
.
newlyDeployed
)
{
if
(
postDeployAction
)
{
const
signer
=
hre
.
ethers
.
provider
.
getSigner
(
deployer
)
let
abi
=
result
.
abi
if
(
iface
!==
undefined
)
{
const
factory
=
await
hre
.
ethers
.
getContractFactory
(
iface
)
abi
=
factory
.
interface
}
const
instance
=
new
Contract
(
result
.
address
,
abi
,
signer
)
await
postDeployAction
(
instance
)
}
await
registerAddress
({
await
registerAddress
({
hre
,
hre
,
name
,
name
,
...
...
packages/core-utils/src/common/hex-strings.ts
View file @
d7978cfc
/* Imports: External */
/* Imports: External */
import
{
BigNumber
}
from
'
ethers
'
import
{
BigNumber
,
ethers
}
from
'
ethers
'
/**
/**
* Removes "0x" from start of a string if it exists.
* Removes "0x" from start of a string if it exists.
...
@@ -80,3 +80,15 @@ export const padHexString = (str: string, length: number): string => {
...
@@ -80,3 +80,15 @@ export const padHexString = (str: string, length: number): string => {
export
const
encodeHex
=
(
val
:
any
,
len
:
number
)
=>
export
const
encodeHex
=
(
val
:
any
,
len
:
number
)
=>
remove0x
(
BigNumber
.
from
(
val
).
toHexString
()).
padStart
(
len
,
'
0
'
)
remove0x
(
BigNumber
.
from
(
val
).
toHexString
()).
padStart
(
len
,
'
0
'
)
export
const
hexStringEquals
=
(
stringA
:
string
,
stringB
:
string
):
boolean
=>
{
if
(
!
ethers
.
utils
.
isHexString
(
stringA
))
{
throw
new
Error
(
`input is not a hex string:
${
stringA
}
`
)
}
if
(
!
ethers
.
utils
.
isHexString
(
stringB
))
{
throw
new
Error
(
`input is not a hex string:
${
stringB
}
`
)
}
return
stringA
.
toLowerCase
()
===
stringB
.
toLowerCase
()
}
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