Skip to content

Commit

Permalink
Creates2 deploy script
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Lima committed Nov 9, 2023
1 parent 21c375d commit 0c694f0
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 6 deletions.
3 changes: 3 additions & 0 deletions addresses/mumbai/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@
"operator": "0x61c22C4e709c3027ecCCdd6ee562BB583Db9a17f",
"implementation": "0x92Ea5e9D5341F10eb6291BB72F3C9e617090952C",
"proxyAdmin": "0x3033689fB46FDe57789A8c84AD1C9bD3A8217985"
},
"ImmutableOwnerCreate2Factory": {
"address": "0x066f91a9Aa4C33D4ea4c12aBee6f4cb4e919F71d"
}
}
3 changes: 3 additions & 0 deletions addresses/polygon/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@
"operator": "0x359E1208DE02Af11461A37D72165Ef2dcD2Adfc8",
"implementation": "0x69C9457dC1FDf2E84C4e45402967f3b88Cc6FF00",
"proxyAdmin": "0x48c769f6a8de57d824f0e7330d7A27dee53a43cD"
},
"ImmutableOwnerCreate2Factory": {
"address": "0x066f91a9Aa4C33D4ea4c12aBee6f4cb4e919F71d"
}
}
9 changes: 9 additions & 0 deletions contracts/interfaces/IImmutableOwnerCreate2Factory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.9;


interface IImmutableOwnerCreate2Factory {
function deploy(bytes32 salt, bytes memory bytecode) external returns (address);
function computeAddress(bytes32 salt, bytes32 bytecodeHash) external view returns (address);
}
47 changes: 41 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@typechain/ethers-v5": "^10.1.0",
"@typechain/hardhat": "^6.1.3",
"@types/mocha": "^10.0.1",
"@types/node": "^20.9.0",
"chai": "^4.3.6",
"ethers": "^5.7.1",
"hardhat": "2.11.2",
Expand Down
148 changes: 148 additions & 0 deletions scripts/04-create2-deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import hre, { ethers, network, upgrades } from 'hardhat'
import { AwsKmsSigner } from '@govtechsg/ethers-aws-kms-signer'
import { confirmOrDie, print, colors } from '../utils/misc'
import addresses, { Network } from '../addresses'
import { THREE_MONTHS } from '../utils/constants'
import config from '../addresses'
import { keccak256 } from 'ethers/lib/utils'
import TransparentUpgradeableProxy from '@openzeppelin/upgrades-core/artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json'
import { updateJsonFile } from '../utils/json'

const kmsCredentials = {
accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'AKIAxxxxxxxxxxxxxxxx', // credentials for your IAM user with KMS access
secretAccessKey: process.env.AWS_ACCESS_KEY_SECRET || 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // credentials for your IAM user with KMS access
region: 'us-east-1', // region of your KMS key
keyId: process.env.AWS_KMS_KEY_ID || 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', // KMS key id
}

const NETWORK = network.name as Network
const { Multisig, RolesRegistry } = addresses[NETWORK]

const CONTRACT_NAME = 'OriumMarketplace'
const OPERATOR_ADDRESS = Multisig.address
const MAX_DEADLINE = THREE_MONTHS.toString()
const INITIALIZER_ARGUMENTS: string[] = [OPERATOR_ADDRESS, RolesRegistry.address, MAX_DEADLINE]

const networkConfig: any = network.config
const provider = new ethers.providers.JsonRpcProvider(networkConfig.url || '')
const deployer = new AwsKmsSigner(kmsCredentials).connect(provider)

async function main() {
const deployerAddress = await deployer.getAddress()
await confirmOrDie(
`Are you sure you want to deploy ${CONTRACT_NAME} to ${NETWORK} using ${deployerAddress} for deployer and ${OPERATOR_ADDRESS} as operator?`,
)

print(colors.highlight, `Deploying ProxyAdmin to ${NETWORK}...`)
const proxyAdminAddress = await upgrades.deployProxyAdmin(deployer)
print(colors.success, `ProxyAdmin deployed to ${NETWORK} at ${proxyAdminAddress}`)

print(colors.highlight, `Deploying implementation to ${NETWORK}...`)
const ImplementationFactory = await ethers.getContractFactory(CONTRACT_NAME, deployer)
const implementation = await ImplementationFactory.deploy()
await implementation.deployed()
print(colors.success, `Implementation deployed to ${NETWORK} at ${implementation.address}`)

print(colors.highlight, `Deploying proxy to ${NETWORK} with CREATE2...`)

const create2Factory = await ethers.getContractAt(
'IImmutableOwnerCreate2Factory',
config[NETWORK].ImmutableOwnerCreate2Factory.address,
deployer,
)

const salt = '0x00000000000000000000000000000000000000008b99e5a778edb02572010000'
const initData = ImplementationFactory.interface.encodeFunctionData('initialize', INITIALIZER_ARGUMENTS)
const TransparentUpgradeableProxyFactory = await ethers.getContractFactory(
TransparentUpgradeableProxy.abi,
TransparentUpgradeableProxy.bytecode,
deployer,
)
const bytecode = ethers.utils.concat([
TransparentUpgradeableProxyFactory.bytecode,
ethers.utils.defaultAbiCoder.encode(
['address', 'address', 'bytes'],
[implementation.address, proxyAdminAddress, initData],
),
])

const proxyContractAddress = await create2Factory.computeAddress(salt, keccak256(bytecode))
print(colors.highlight, `Proxy will be deployed to ${proxyContractAddress}, deploying...`)

const tx = await create2Factory.deploy(salt, bytecode)
print(colors.highlight, `Waiting for transaction to be mined..., tx: ${tx.hash}`)
await tx.wait()
print(colors.success, `Proxy deployed to ${proxyContractAddress}`)

// Force upgrade proxy
try {
print(colors.highlight, `Fetching proxy network files...`)
await upgrades.forceImport(proxyContractAddress, ImplementationFactory, { kind: 'transparent' })
print(colors.success, `Proxy network files fetched`)
} catch (e) {
print(colors.error, `Proxy network files not found`)
console.error(e)
}

try {
print(colors.highlight, `Verifying proxy...`)
await hre.run('verify:verify', {
address: proxyContractAddress,
constructorArguments: [],
})
print(colors.success, `Proxy verified!`)
} catch (e) {
// it will fail to verify proxy because transaction hash is different than the one used to verify
/* print(colors.error, `Proxy not verified`)
console.error(e) */
}

print(colors.highlight, 'Updating config files...')
const deploymentInfo = {
[CONTRACT_NAME]: {
address: proxyContractAddress,
operator: OPERATOR_ADDRESS,
implementation: implementation.address,
proxyAdmin: proxyAdminAddress,
},
}

console.log(deploymentInfo)

updateJsonFile(`addresses/${NETWORK}/index.json`, deploymentInfo)

print(colors.success, 'Config files updated!')

try {
print(colors.highlight, 'Transferring proxy admin ownership...')
const abi = [
{
inputs: [
{
internalType: 'address',
name: 'newOwner',
type: 'address',
},
],
name: 'transferOwnership',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
]
const proxyAdminContract = new ethers.Contract(deploymentInfo[CONTRACT_NAME].proxyAdmin, abi, deployer)
await proxyAdminContract.transferOwnership(OPERATOR_ADDRESS)
print(colors.success, `Proxy admin ownership transferred to: ${OPERATOR_ADDRESS}`)
} catch (e) {
print(colors.error, `Error transferring proxy admin ownership: ${e}`)
}
}

main()
.then(async () => {
print(colors.bigSuccess, 'All done!')
})
.catch(error => {
console.error(error)
process.exitCode = 1
})

0 comments on commit 0c694f0

Please sign in to comment.