-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Daniel Lima
committed
Nov 9, 2023
1 parent
21c375d
commit 0c694f0
Showing
6 changed files
with
205 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
}) |