Commit 483f561b authored by Kelvin Fichter's avatar Kelvin Fichter

feat: solidify deployment process

Various fixes to make the deployment process easier
parent bfeb7fba
---
'@eth-optimism/contracts': patch
---
Update and harden the contract deployment process
import { expect } from 'chai'
/* Imports: External */ /* Imports: External */
import { import {
Contract, Contract,
...@@ -86,14 +84,14 @@ export const getAddressManager = (provider: any) => { ...@@ -86,14 +84,14 @@ export const getAddressManager = (provider: any) => {
export const getL1Bridge = async (wallet: Wallet, AddressManager: Contract) => { export const getL1Bridge = async (wallet: Wallet, AddressManager: Contract) => {
const l1BridgeInterface = getContractInterface('L1StandardBridge') const l1BridgeInterface = getContractInterface('L1StandardBridge')
const ProxyBridgeAddress = await AddressManager.getAddress( const ProxyBridgeAddress = await AddressManager.getAddress(
'Proxy__L1StandardBridge' 'Proxy__OVM_L1StandardBridge'
) )
if ( if (
!utils.isAddress(ProxyBridgeAddress) || !utils.isAddress(ProxyBridgeAddress) ||
ProxyBridgeAddress === constants.AddressZero ProxyBridgeAddress === constants.AddressZero
) { ) {
throw new Error('Proxy__L1StandardBridge not found') throw new Error('Proxy__OVM_L1StandardBridge not found')
} }
const L1StandardBridge = new Contract( const L1StandardBridge = new Contract(
......
...@@ -13,7 +13,7 @@ export const initWatcher = async ( ...@@ -13,7 +13,7 @@ export const initWatcher = async (
AddressManager: Contract AddressManager: Contract
) => { ) => {
const l1MessengerAddress = await AddressManager.getAddress( const l1MessengerAddress = await AddressManager.getAddress(
'Proxy__L1CrossDomainMessenger' 'Proxy__OVM_L1CrossDomainMessenger'
) )
const l2MessengerAddress = await AddressManager.getAddress( const l2MessengerAddress = await AddressManager.getAddress(
'L2CrossDomainMessenger' 'L2CrossDomainMessenger'
......
...@@ -24,12 +24,12 @@ function envSet() { ...@@ -24,12 +24,12 @@ function envSet() {
} }
# set the address to the proxy gateway if possible # set the address to the proxy gateway if possible
envSet L1_STANDARD_BRIDGE_ADDRESS Proxy__L1StandardBridge envSet L1_STANDARD_BRIDGE_ADDRESS Proxy__OVM_L1StandardBridge
if [ $L1_STANDARD_BRIDGE_ADDRESS == null ]; then if [ $L1_STANDARD_BRIDGE_ADDRESS == null ]; then
envSet L1_STANDARD_BRIDGE_ADDRESS L1StandardBridge envSet L1_STANDARD_BRIDGE_ADDRESS L1StandardBridge
fi fi
envSet L1_CROSS_DOMAIN_MESSENGER_ADDRESS Proxy__L1CrossDomainMessenger envSet L1_CROSS_DOMAIN_MESSENGER_ADDRESS Proxy__OVM_L1CrossDomainMessenger
if [ $L1_CROSS_DOMAIN_MESSENGER_ADDRESS == null ]; then if [ $L1_CROSS_DOMAIN_MESSENGER_ADDRESS == null ]; then
envSet L1_CROSS_DOMAIN_MESSENGER_ADDRESS L1CrossDomainMessenger envSet L1_CROSS_DOMAIN_MESSENGER_ADDRESS L1CrossDomainMessenger
fi fi
......
// WARNING: DO NOT USE THIS FILE TO DEPLOY CONTRACTS TO PRODUCTION
// WE ARE REMOVING THIS FILE IN A FUTURE RELEASE, IT IS ONLY TO BE USED AS PART OF THE LOCAL
// DEPLOYMENT PROCESS. USE A DEPLOYMENT SCRIPT LOCATED IN scripts/deploy-scripts/ WHEN DEPLOYING
// TO A PRODUCTION ENVIRONMENT.
import { Wallet } from 'ethers' import { Wallet } from 'ethers'
import path from 'path' import path from 'path'
import dirtree from 'directory-tree' import dirtree from 'directory-tree'
...@@ -43,6 +48,11 @@ const parseEnv = () => { ...@@ -43,6 +48,11 @@ const parseEnv = () => {
} }
const main = async () => { const main = async () => {
// Just be really verbose about this...
console.log(
`WARNING: DO NOT USE THIS FILE IN PRODUCTION! FOR LOCAL DEVELOPMENT ONLY!`
)
const config = parseEnv() const config = parseEnv()
await hre.run('deploy', { await hre.run('deploy', {
...@@ -55,6 +65,7 @@ const main = async () => { ...@@ -55,6 +65,7 @@ const main = async () => {
ovmSequencerAddress: sequencer.address, ovmSequencerAddress: sequencer.address,
ovmProposerAddress: sequencer.address, ovmProposerAddress: sequencer.address,
ovmAddressManagerOwner: deployer.address, ovmAddressManagerOwner: deployer.address,
numDeployConfirmations: 0,
noCompile: process.env.NO_COMPILE ? true : false, noCompile: process.env.NO_COMPILE ? true : false,
}) })
......
...@@ -9,6 +9,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -9,6 +9,7 @@ const deployFn: DeployFunction = async (hre) => {
from: deployer, from: deployer,
args: [], args: [],
log: true, log: true,
waitConfirmations: (hre as any).deployConfig.numDeployConfirmations,
}) })
} }
......
...@@ -17,12 +17,12 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -17,12 +17,12 @@ const deployFn: DeployFunction = async (hre) => {
await deployAndRegister({ await deployAndRegister({
hre, hre,
name: 'Proxy__L1CrossDomainMessenger', name: 'Proxy__OVM_L1CrossDomainMessenger',
contract: 'Lib_ResolvedDelegateProxy', contract: 'Lib_ResolvedDelegateProxy',
iface: 'L1CrossDomainMessenger', iface: 'L1CrossDomainMessenger',
args: [Lib_AddressManager.address, 'OVM_L1CrossDomainMessenger'], args: [Lib_AddressManager.address, 'OVM_L1CrossDomainMessenger'],
postDeployAction: async (contract) => { postDeployAction: async (contract) => {
console.log(`Initializing Proxy__L1CrossDomainMessenger...`) console.log(`Initializing Proxy__OVM_L1CrossDomainMessenger...`)
await contract.initialize(Lib_AddressManager.address) await contract.initialize(Lib_AddressManager.address)
console.log(`Checking that contract was correctly initialized...`) console.log(`Checking that contract was correctly initialized...`)
...@@ -36,6 +36,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -36,6 +36,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['Proxy__L1CrossDomainMessenger'] deployFn.tags = ['Proxy__OVM_L1CrossDomainMessenger']
export default deployFn export default deployFn
...@@ -9,13 +9,13 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -9,13 +9,13 @@ const deployFn: DeployFunction = async (hre) => {
await deployAndRegister({ await deployAndRegister({
hre, hre,
name: 'Proxy__L1StandardBridge', name: 'Proxy__OVM_L1StandardBridge',
contract: 'L1ChugSplashProxy', contract: 'L1ChugSplashProxy',
iface: 'L1StandardBridge', iface: 'L1StandardBridge',
args: [deployer], args: [deployer],
}) })
} }
deployFn.tags = ['Proxy__L1StandardBridge'] deployFn.tags = ['Proxy__OVM_L1StandardBridge']
export default deployFn export default deployFn
...@@ -12,6 +12,8 @@ import { ...@@ -12,6 +12,8 @@ import {
import { import {
getDeployedContract, getDeployedContract,
waitUntilTrue, waitUntilTrue,
getAdvancedContract,
deployAndRegister,
} from '../src/hardhat-deploy-ethers' } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
...@@ -22,21 +24,28 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -22,21 +24,28 @@ const deployFn: DeployFunction = async (hre) => {
) )
// Set up a reference to the proxy as if it were the L1StandardBridge contract. // Set up a reference to the proxy as if it were the L1StandardBridge contract.
const contract = await getDeployedContract(hre, 'Proxy__L1StandardBridge', { const contract = await getDeployedContract(
hre,
'Proxy__OVM_L1StandardBridge',
{
iface: 'L1StandardBridge', iface: 'L1StandardBridge',
signerOrProvider: deployer, signerOrProvider: deployer,
}) }
)
// Because of the `iface` parameter supplied to the deployment function above, the `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, // 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 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 // we instantiate a new ethers.Contract object with the same address and signer but with the
// L1ChugSplashProxy interface. // L1ChugSplashProxy interface.
const proxy = new ethers.Contract( const proxy = getAdvancedContract({
hre,
contract: new ethers.Contract(
contract.address, contract.address,
getContractInterface('L1ChugSplashProxy'), getContractInterface('L1ChugSplashProxy'),
contract.signer contract.signer
) ),
})
// First we need to set the correct implementation code. We'll set the code and then check // First we need to set the correct implementation code. We'll set the code and then check
// that the code was indeed correctly set. // that the code was indeed correctly set.
...@@ -62,10 +71,17 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -62,10 +71,17 @@ const deployFn: DeployFunction = async (hre) => {
// check that this operation was correctly executed by calling `messenger()` and checking // check that this operation was correctly executed by calling `messenger()` and checking
// that the result matches the value we initialized. // that the result matches the value we initialized.
const l1CrossDomainMessengerAddress = await Lib_AddressManager.getAddress( const l1CrossDomainMessengerAddress = await Lib_AddressManager.getAddress(
'Proxy__L1CrossDomainMessenger' 'Proxy__OVM_L1CrossDomainMessenger'
) )
console.log(`Setting messenger address...`) // Critical error, should never happen.
if (
hexStringEquals(l1CrossDomainMessengerAddress, ethers.constants.AddressZero)
) {
throw new Error(`L1CrossDomainMessenger address is set to address(0)`)
}
console.log(`Setting messenger address to ${l1CrossDomainMessengerAddress}...`)
await proxy.setStorage( await proxy.setStorage(
ethers.utils.hexZeroPad('0x00', 32), ethers.utils.hexZeroPad('0x00', 32),
ethers.utils.hexZeroPad(l1CrossDomainMessengerAddress, 32) ethers.utils.hexZeroPad(l1CrossDomainMessengerAddress, 32)
...@@ -80,7 +96,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -80,7 +96,7 @@ const deployFn: DeployFunction = async (hre) => {
}) })
// Now we set the bridge address in the same manner as the messenger address. // Now we set the bridge address in the same manner as the messenger address.
console.log(`Setting l2 bridge address...`) console.log(`Setting l2 bridge address to ${predeploys.L2StandardBridge}...`)
await proxy.setStorage( await proxy.setStorage(
ethers.utils.hexZeroPad('0x01', 32), ethers.utils.hexZeroPad('0x01', 32),
ethers.utils.hexZeroPad(predeploys.L2StandardBridge, 32) ethers.utils.hexZeroPad(predeploys.L2StandardBridge, 32)
...@@ -95,8 +111,8 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -95,8 +111,8 @@ const deployFn: DeployFunction = async (hre) => {
}) })
// Finally we transfer ownership of the proxy to the ovmAddressManagerOwner address. // Finally we transfer ownership of the proxy to the ovmAddressManagerOwner address.
console.log(`Setting owner address...`)
const owner = (hre as any).deployConfig.ovmAddressManagerOwner const owner = (hre as any).deployConfig.ovmAddressManagerOwner
console.log(`Setting owner address to ${owner}...`)
await proxy.setOwner(owner) await proxy.setOwner(owner)
console.log(`Confirming that owner address was correctly set...`) console.log(`Confirming that owner address was correctly set...`)
...@@ -108,6 +124,15 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -108,6 +124,15 @@ const deployFn: DeployFunction = async (hre) => {
owner owner
) )
}) })
// Deploy a copy of the implementation so it can be successfully verified on Etherscan.
console.log(`Deploying a copy of the bridge for Etherscan verification...`)
await deployAndRegister({
hre,
name: 'L1StandardBridge_for_verification_only',
contract: 'L1StandardBridge',
args: [],
})
} }
deployFn.tags = ['L1StandardBridge', 'upgrade'] deployFn.tags = ['L1StandardBridge', 'upgrade']
......
...@@ -19,7 +19,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -19,7 +19,7 @@ const deployFn: DeployFunction = async (hre) => {
if (chainId === defaultHardhatNetworkParams.chainId) { if (chainId === defaultHardhatNetworkParams.chainId) {
const L1StandardBridge = await getDeployedContract( const L1StandardBridge = await getDeployedContract(
hre, hre,
'Proxy__L1StandardBridge', 'Proxy__OVM_L1StandardBridge',
{ {
iface: 'L1StandardBridge', iface: 'L1StandardBridge',
} }
......
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
"ethers": "^5.4.5", "ethers": "^5.4.5",
"glob": "^7.1.6", "glob": "^7.1.6",
"hardhat": "^2.3.0", "hardhat": "^2.3.0",
"hardhat-deploy": "^0.7.4", "hardhat-deploy": "^0.9.3",
"hardhat-gas-reporter": "^1.0.4", "hardhat-gas-reporter": "^1.0.4",
"lint-staged": "11.0.0", "lint-staged": "11.0.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
......
...@@ -23,14 +23,17 @@ npx hardhat deploy \ ...@@ -23,14 +23,17 @@ npx hardhat deploy \
--ctc-max-transaction-gas-limit 15000000 \ --ctc-max-transaction-gas-limit 15000000 \
--ctc-l2-gas-discount-divisor 32 \ --ctc-l2-gas-discount-divisor 32 \
--ctc-enqueue-gas-cost 60000 \ --ctc-enqueue-gas-cost 60000 \
--scc-fraud-proof-window 604800 \ --scc-fraud-proof-window 10 \
--scc-sequencer-publish-window 12592000 \ --scc-sequencer-publish-window 12592000 \
--ovm-sequencer-address 0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244 \ --ovm-sequencer-address 0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244 \
--ovm-proposer-address 0x9A2F243c605e6908D96b18e21Fb82Bf288B19EF3 \ --ovm-proposer-address 0x9A2F243c605e6908D96b18e21Fb82Bf288B19EF3 \
--ovm-address-manager-owner 0x18394B52d3Cb931dfA76F63251919D051953413d \ --ovm-address-manager-owner 0x18394B52d3Cb931dfA76F63251919D051953413d \
--gasprice 10000000000 \ --gasprice 1000000000 \
--num-deploy-confirmations 1 \
--tags upgrade \ --tags upgrade \
--network kovan --network kovan
CONTRACTS_TARGET_NETWORK=kovan \ CONTRACTS_TARGET_NETWORK=kovan \
npx hardhat etherscan-verify --network kovan npx hardhat etherscan-verify \
--network kovan \
--sleep
...@@ -74,7 +74,7 @@ const networks = { ...@@ -74,7 +74,7 @@ const networks = {
if (contracts[i] === 'L1CrossDomainMessenger') { if (contracts[i] === 'L1CrossDomainMessenger') {
proxiedContracts.push(contracts.splice(i, 1)[0]) proxiedContracts.push(contracts.splice(i, 1)[0])
} }
if (contracts[i] === 'Proxy__L1StandardBridge') { if (contracts[i] === 'L1StandardBridge') {
proxiedContracts.push(contracts.splice(i, 1)[0]) proxiedContracts.push(contracts.splice(i, 1)[0])
} }
} }
......
...@@ -81,6 +81,7 @@ export const deployAndRegister = async ({ ...@@ -81,6 +81,7 @@ export const deployAndRegister = async ({
from: deployer, from: deployer,
args, args,
log: true, log: true,
waitConfirmations: hre.deployConfig.numDeployConfirmations,
}) })
await hre.ethers.provider.waitForTransaction(result.transactionHash) await hre.ethers.provider.waitForTransaction(result.transactionHash)
...@@ -93,8 +94,12 @@ export const deployAndRegister = async ({ ...@@ -93,8 +94,12 @@ export const deployAndRegister = async ({
const factory = await hre.ethers.getContractFactory(iface) const factory = await hre.ethers.getContractFactory(iface)
abi = factory.interface abi = factory.interface
} }
const instance = new Contract(result.address, abi, signer) await postDeployAction(
await postDeployAction(instance) getAdvancedContract({
hre,
contract: new Contract(result.address, abi, signer),
})
)
} }
await registerAddress({ await registerAddress({
...@@ -105,6 +110,71 @@ export const deployAndRegister = async ({ ...@@ -105,6 +110,71 @@ export const deployAndRegister = async ({
} }
} }
// Returns a version of the contract object which modifies all of the input contract's methods to:
// 1. Waits for a confirmed receipt with more than deployConfig.numDeployConfirmations confirmations.
// 2. Include simple resubmission logic, ONLY for Kovan, which appears to drop transactions.
export const getAdvancedContract = (opts: {
hre: any
contract: Contract
}): Contract => {
// Temporarily override Object.defineProperty to bypass ether's object protection.
const def = Object.defineProperty
Object.defineProperty = (obj, propName, prop) => {
prop.writable = true
return def(obj, propName, prop)
}
const contract = new Contract(
opts.contract.address,
opts.contract.interface,
opts.contract.signer || opts.contract.provider
)
// Now reset Object.defineProperty
Object.defineProperty = def
// Override each function call to also `.wait()` so as to simplify the deploy scripts' syntax.
for (const fnName of Object.keys(contract.functions)) {
const fn = contract[fnName].bind(contract)
;(contract as any)[fnName] = async (...args: any) => {
const tx = await fn(...args, {
gasPrice: opts.hre.deployConfig.gasprice || undefined,
})
if (typeof tx !== 'object' || typeof tx.wait !== 'function') {
return tx
}
// Special logic for:
// (1) handling confirmations
// (2) handling an issue on Kovan specifically where transactions get dropped for no
// apparent reason.
const maxTimeout = 120
let timeout = 0
while (true) {
await sleep(1000)
const receipt = await contract.provider.getTransactionReceipt(tx.hash)
if (receipt === null) {
timeout++
if (timeout > maxTimeout && opts.hre.network.name === 'kovan') {
// Special resubmission logic ONLY required on Kovan.
console.log(
`WARNING: Exceeded max timeout on transaction. Attempting to submit transaction again...`
)
return contract[fnName](...args)
}
} else if (
receipt.confirmations >= opts.hre.deployConfig.numDeployConfirmations
) {
return tx
}
}
}
}
return contract
}
export const getDeployedContract = async ( export const getDeployedContract = async (
hre: any, hre: any,
name: string, name: string,
...@@ -133,29 +203,8 @@ export const getDeployedContract = async ( ...@@ -133,29 +203,8 @@ export const getDeployedContract = async (
} }
} }
// Temporarily override Object.defineProperty to bypass ether's object protection. return getAdvancedContract({
const def = Object.defineProperty hre,
Object.defineProperty = (obj, propName, prop) => { contract: new Contract(deployed.address, iface, signerOrProvider),
prop.writable = true })
return def(obj, propName, prop)
}
const contract = new Contract(deployed.address, iface, signerOrProvider)
// Now reset Object.defineProperty
Object.defineProperty = def
// Override each function call to also `.wait()` so as to simplify the deploy scripts' syntax.
for (const fnName of Object.keys(contract.functions)) {
const fn = contract[fnName].bind(contract)
;(contract as any)[fnName] = async (...args: any) => {
const result = await fn(...args)
if (typeof result === 'object' && typeof result.wait === 'function') {
await result.wait()
}
return result
}
}
return contract
} }
...@@ -9,6 +9,7 @@ const DEFAULT_CTC_L2_GAS_DISCOUNT_DIVISOR = 32 ...@@ -9,6 +9,7 @@ const DEFAULT_CTC_L2_GAS_DISCOUNT_DIVISOR = 32
const DEFAULT_CTC_ENQUEUE_GAS_COST = 60_000 const DEFAULT_CTC_ENQUEUE_GAS_COST = 60_000
const DEFAULT_SCC_FRAUD_PROOF_WINDOW = 60 * 60 * 24 * 7 // 7 days const DEFAULT_SCC_FRAUD_PROOF_WINDOW = 60 * 60 * 24 * 7 // 7 days
const DEFAULT_SCC_SEQUENCER_PUBLISH_WINDOW = 60 * 30 // 30 minutes const DEFAULT_SCC_SEQUENCER_PUBLISH_WINDOW = 60 * 30 // 30 minutes
const DEFAULT_DEPLOY_CONFIRMATIONS = 12
task('deploy') task('deploy')
.addOptionalParam( .addOptionalParam(
...@@ -65,6 +66,12 @@ task('deploy') ...@@ -65,6 +66,12 @@ task('deploy')
undefined, undefined,
types.string types.string
) )
.addOptionalParam(
'numDeployConfirmations',
'Number of confirmations to wait for each transaction in the deployment. More is safer.',
DEFAULT_DEPLOY_CONFIRMATIONS,
types.int
)
.setAction(async (args, hre: any, runSuper) => { .setAction(async (args, hre: any, runSuper) => {
// Necessary because hardhat doesn't let us attach non-optional parameters to existing tasks. // Necessary because hardhat doesn't let us attach non-optional parameters to existing tasks.
const validateAddressArg = (argName: string) => { const validateAddressArg = (argName: string) => {
......
...@@ -111,7 +111,7 @@ export class MessageRelayerService extends BaseService<MessageRelayerOptions> { ...@@ -111,7 +111,7 @@ export class MessageRelayerService extends BaseService<MessageRelayerOptions> {
this.logger.info('Connecting to L1CrossDomainMessenger...') this.logger.info('Connecting to L1CrossDomainMessenger...')
this.state.L1CrossDomainMessenger = await loadContractFromManager({ this.state.L1CrossDomainMessenger = await loadContractFromManager({
name: 'L1CrossDomainMessenger', name: 'L1CrossDomainMessenger',
proxy: 'Proxy__L1CrossDomainMessenger', proxy: 'Proxy__OVM_L1CrossDomainMessenger',
Lib_AddressManager: this.state.Lib_AddressManager, Lib_AddressManager: this.state.Lib_AddressManager,
provider: this.options.l1RpcProvider, provider: this.options.l1RpcProvider,
}) })
......
...@@ -783,6 +783,15 @@ ...@@ -783,6 +783,15 @@
"@ethersproject/logger" "^5.4.0" "@ethersproject/logger" "^5.4.0"
bn.js "^4.11.9" bn.js "^4.11.9"
"@ethersproject/bignumber@^5.4.1":
version "5.4.2"
resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.4.2.tgz#44232e015ae4ce82ac034de549eb3583c71283d8"
integrity sha512-oIBDhsKy5bs7j36JlaTzFgNPaZjiNDOXsdSgSpXRucUl+UA6L/1YLlFeI3cPAoodcenzF4nxNPV13pcy7XbWjA==
dependencies:
"@ethersproject/bytes" "^5.4.0"
"@ethersproject/logger" "^5.4.0"
bn.js "^4.11.9"
"@ethersproject/bytes@5.4.0", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.4.0": "@ethersproject/bytes@5.4.0", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.4.0":
version "5.4.0" version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.4.0.tgz#56fa32ce3bf67153756dbaefda921d1d4774404e" resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.4.0.tgz#56fa32ce3bf67153756dbaefda921d1d4774404e"
...@@ -936,7 +945,7 @@ ...@@ -936,7 +945,7 @@
bech32 "1.1.4" bech32 "1.1.4"
ws "7.4.6" ws "7.4.6"
"@ethersproject/providers@^5.4.5": "@ethersproject/providers@^5.4.4", "@ethersproject/providers@^5.4.5":
version "5.4.5" version "5.4.5"
resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.4.5.tgz#eb2ea2a743a8115f79604a8157233a3a2c832928" resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.4.5.tgz#eb2ea2a743a8115f79604a8157233a3a2c832928"
integrity sha512-1GkrvkiAw3Fj28cwi1Sqm8ED1RtERtpdXmRfwIBGmqBSN5MoeRUHuwHPppMtbPayPgpFcvD7/Gdc9doO5fGYgw== integrity sha512-1GkrvkiAw3Fj28cwi1Sqm8ED1RtERtpdXmRfwIBGmqBSN5MoeRUHuwHPppMtbPayPgpFcvD7/Gdc9doO5fGYgw==
...@@ -998,7 +1007,7 @@ ...@@ -998,7 +1007,7 @@
elliptic "6.5.4" elliptic "6.5.4"
hash.js "1.1.7" hash.js "1.1.7"
"@ethersproject/solidity@5.4.0", "@ethersproject/solidity@^5.0.0", "@ethersproject/solidity@^5.0.9": "@ethersproject/solidity@5.4.0", "@ethersproject/solidity@^5.0.0", "@ethersproject/solidity@^5.0.9", "@ethersproject/solidity@^5.4.0":
version "5.4.0" version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.4.0.tgz#1305e058ea02dc4891df18b33232b11a14ece9ec" resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.4.0.tgz#1305e058ea02dc4891df18b33232b11a14ece9ec"
integrity sha512-XFQTZ7wFSHOhHcV1DpcWj7VXECEiSrBuv7JErJvB9Uo+KfCdc3QtUZV+Vjh/AAaYgezUEKbCtE6Khjm44seevQ== integrity sha512-XFQTZ7wFSHOhHcV1DpcWj7VXECEiSrBuv7JErJvB9Uo+KfCdc3QtUZV+Vjh/AAaYgezUEKbCtE6Khjm44seevQ==
...@@ -1042,7 +1051,7 @@ ...@@ -1042,7 +1051,7 @@
"@ethersproject/constants" "^5.4.0" "@ethersproject/constants" "^5.4.0"
"@ethersproject/logger" "^5.4.0" "@ethersproject/logger" "^5.4.0"
"@ethersproject/wallet@5.4.0", "@ethersproject/wallet@^5.0.0": "@ethersproject/wallet@5.4.0", "@ethersproject/wallet@^5.0.0", "@ethersproject/wallet@^5.4.0":
version "5.4.0" version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.4.0.tgz#fa5b59830b42e9be56eadd45a16a2e0933ad9353" resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.4.0.tgz#fa5b59830b42e9be56eadd45a16a2e0933ad9353"
integrity sha512-wU29majLjM6AjCjpat21mPPviG+EpK7wY1+jzKD0fg3ui5fgedf2zEu1RDgpfIMsfn8fJHJuzM4zXZ2+hSHaSQ== integrity sha512-wU29majLjM6AjCjpat21mPPviG+EpK7wY1+jzKD0fg3ui5fgedf2zEu1RDgpfIMsfn8fJHJuzM4zXZ2+hSHaSQ==
...@@ -2741,7 +2750,7 @@ ...@@ -2741,7 +2750,7 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3"
integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog== integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==
"@types/qs@*", "@types/qs@^6.2.31", "@types/qs@^6.9.4": "@types/qs@*", "@types/qs@^6.2.31", "@types/qs@^6.9.7":
version "6.9.7" version "6.9.7"
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==
...@@ -4694,7 +4703,7 @@ chalk@^3.0.0: ...@@ -4694,7 +4703,7 @@ chalk@^3.0.0:
ansi-styles "^4.1.0" ansi-styles "^4.1.0"
supports-color "^7.1.0" supports-color "^7.1.0"
chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2:
version "4.1.2" version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
...@@ -4759,7 +4768,7 @@ chokidar@3.5.1: ...@@ -4759,7 +4768,7 @@ chokidar@3.5.1:
optionalDependencies: optionalDependencies:
fsevents "~2.3.1" fsevents "~2.3.1"
chokidar@3.5.2, chokidar@^3.4.0, chokidar@^3.4.3: chokidar@3.5.2, chokidar@^3.4.0, chokidar@^3.4.3, chokidar@^3.5.2:
version "3.5.2" version "3.5.2"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
...@@ -7495,6 +7504,15 @@ form-data@^3.0.0: ...@@ -7495,6 +7504,15 @@ form-data@^3.0.0:
combined-stream "^1.0.8" combined-stream "^1.0.8"
mime-types "^2.1.12" mime-types "^2.1.12"
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
form-data@~2.3.2: form-data@~2.3.2:
version "2.3.3" version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
...@@ -7557,6 +7575,15 @@ fs-extra@^0.30.0: ...@@ -7557,6 +7575,15 @@ fs-extra@^0.30.0:
path-is-absolute "^1.0.0" path-is-absolute "^1.0.0"
rimraf "^2.2.8" rimraf "^2.2.8"
fs-extra@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1"
integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
universalify "^2.0.0"
fs-extra@^4.0.2, fs-extra@^4.0.3: fs-extra@^4.0.2, fs-extra@^4.0.3:
version "4.0.3" version "4.0.3"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94"
...@@ -7584,7 +7611,7 @@ fs-extra@^8.1.0: ...@@ -7584,7 +7611,7 @@ fs-extra@^8.1.0:
jsonfile "^4.0.0" jsonfile "^4.0.0"
universalify "^0.1.0" universalify "^0.1.0"
fs-extra@^9.0.0, fs-extra@^9.1.0: fs-extra@^9.1.0:
version "9.1.0" version "9.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
...@@ -8058,28 +8085,29 @@ hard-rejection@^2.1.0: ...@@ -8058,28 +8085,29 @@ hard-rejection@^2.1.0:
resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883"
integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==
hardhat-deploy@^0.7.4: hardhat-deploy@^0.9.3:
version "0.7.11" version "0.9.3"
resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.7.11.tgz#93f79dfbb529eeda24ac963e23a19064d536be2f" resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.9.3.tgz#cf9a7806c0a86a6f7e9352fc558b26c079983496"
integrity sha512-ONLH3NH8Biuhky44KRFyaINVHM8JI4Ihy1TpntIRZUpIFHlz9h3gieq46H7iwdp6z3CqMsOCChF0riUF3CFpmQ== integrity sha512-0sxxQoxcA1+LSVmmLwp9empK4Pz5tjr92JvfcobojBz35DSpp0o3f0f/tXocYWaGbOrms3eQJ8OX5WVsmcnN4Q==
dependencies: dependencies:
"@ethersproject/abi" "^5.0.0" "@ethersproject/abi" "^5.4.0"
"@ethersproject/abstract-signer" "^5.0.0" "@ethersproject/abstract-signer" "^5.4.1"
"@ethersproject/address" "^5.0.0" "@ethersproject/address" "^5.4.0"
"@ethersproject/bignumber" "^5.0.0" "@ethersproject/bignumber" "^5.4.1"
"@ethersproject/bytes" "^5.0.0" "@ethersproject/bytes" "^5.4.0"
"@ethersproject/contracts" "^5.0.0" "@ethersproject/contracts" "^5.4.1"
"@ethersproject/providers" "^5.0.0" "@ethersproject/providers" "^5.4.4"
"@ethersproject/solidity" "^5.0.0" "@ethersproject/solidity" "^5.4.0"
"@ethersproject/transactions" "^5.0.0" "@ethersproject/transactions" "^5.4.0"
"@ethersproject/wallet" "^5.0.0" "@ethersproject/wallet" "^5.4.0"
"@types/qs" "^6.9.4" "@types/qs" "^6.9.7"
axios "^0.21.1" axios "^0.21.1"
chalk "^4.1.0" chalk "^4.1.2"
chokidar "^3.4.0" chokidar "^3.5.2"
debug "^4.1.1" debug "^4.3.2"
form-data "^3.0.0" enquirer "^2.3.6"
fs-extra "^9.0.0" form-data "^4.0.0"
fs-extra "^10.0.0"
match-all "^1.2.6" match-all "^1.2.6"
murmur-128 "^0.2.1" murmur-128 "^0.2.1"
qs "^6.9.4" qs "^6.9.4"
......
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