Skip to content

Commit

Permalink
Merge pull request #1 from 0xsequence/library
Browse files Browse the repository at this point in the history
Add Library contracts
  • Loading branch information
ScreamingHawk authored Nov 21, 2023
2 parents 4c12d6a + 940591d commit 7d3b4a9
Show file tree
Hide file tree
Showing 15 changed files with 2,616 additions and 33 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ NETWORK_NAME=goerli
RPC_URL=https://goerli.infura.io/v3/xxx

DEPLOYER_PRIVATE_KEY=0x0000000000000000000000000000000000000000000000000000000000042069
GAS_LIMIT= # Optional
GAS_PRICE= # Optional

VERIFIER_API_URL=https://api-goerli.etherscan.io/api
VERIFIER_API_KEY=PLACEHOLDER_STRING
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,9 @@ The following is a list of contracts that are deployed by this script.
| GuardV2 | 0x761f5e29944D79d76656323F106CF2efBF5F09e9 |
| GuardV1 | 0x596aF90CecdBF9A768886E771178fd5561dD27Ab |
| Orderbook | 0x2cF83ECbad9D2c43ab49C512715887Bd812896f1 |
| DeveloperMultisig | 0x007a47e6BF40C1e0ed5c01aE42fDC75879140bc4 |
| ERC20MinterFactory | 0x55ECCa57590740DF0df92CE88DBdF9E8309AE9FC |
| ERC721MinterFactory | 0x0Aab812958e7996bf84A046D07639561bF6495bA |
| ERC721SaleFactory | 0x4482E04D68E5460926F25fB270694e9F5125cb61 |
| ERC1155MinterFactory | 0x04B94e4d62cdC04a7bCc829FE3d423fa5fE1b0bc |
| ERC1155SaleFactory | 0xfBa5ACD43246fc8f7B8661aE92fC5e0317FAab20 |
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
}
},
"dependencies": {
"0xsequence": "^1.2.3",
"@0xsequence/solidity-deployer": "^0.0.4",
"@typechain/ethers-v5": "^7.0.1",
"@typescript-eslint/eslint-plugin": "^4.18.0",
Expand Down
222 changes: 195 additions & 27 deletions scripts/deploy-contracts.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import ora from 'ora'
import ora, { Ora } from 'ora'

import { deployers, verifiers } from '@0xsequence/solidity-deployer'
import { JsonRpcProvider } from '@ethersproject/providers'
import { config as dotenvConfig } from 'dotenv'
import { ethers } from 'ethers'
import fs from 'fs'
import { deployGuard } from './factories/deployers/GuardDeployer'
import { BigNumber, ethers } from 'ethers'
import { writeFile } from 'fs/promises'
import { ORDERBOOK_VERIFICATION, Orderbook } from './factories/orderbook/Orderbook'
import { ERC1155MINTERFACTORY_VERIFICATION, ERC1155MinterFactory } from './factories/token_library/ERC1155MinterFactory'
import { ERC1155SALEFACTORY_VERIFICATION, ERC1155SaleFactory } from './factories/token_library/ERC1155SaleFactory'
import { ERC20MINTERFACTORY_VERIFICATION, ERC20MinterFactory } from './factories/token_library/ERC20MinterFactory'
import { ERC721MINTERFACTORY_VERIFICATION, ERC721MinterFactory } from './factories/token_library/ERC721MinterFactory'
import { ERC721SALEFACTORY_VERIFICATION, ERC721SaleFactory } from './factories/token_library/ERC721SaleFactory'
import {
FactoryV1,
GuestModuleV1,
Expand All @@ -13,47 +19,67 @@ import {
RequireFreshSignerV1,
SequenceUtilsV1
} from './factories/v1'
import { FactoryV2, GuestModuleV2, MainModuleUpgradableV2, MainModuleV2, SequenceUtilsV2 } from './factories/v2'
import { deployers, verifiers } from '@0xsequence/solidity-deployer'
import { FACTORY_V1_VERIFICATION } from './factories/v1/FactoryV1'
import { GUEST_MODULE_V1_VERIFICATION } from './factories/v1/GuestModuleV1'
import { MAIN_MODULE_V1_VERIFICATION } from './factories/v1/MainModuleV1'
import { MAIN_MODULE_UPGRADABLE_V1_VERIFICATION } from './factories/v1/MainModuleUpgradableV1'
import { FACTORY_V1_VERIFICATION } from './factories/v1/FactoryV1'
import { SEQUENCE_UTILS_V1_VERIFICATION } from './factories/v1/SequenceUtilsV1'
import { MAIN_MODULE_V1_VERIFICATION } from './factories/v1/MainModuleV1'
import { REQUIRE_FRESH_SIGNER_V1_VERIFICATION } from './factories/v1/RequireFreshSignerV1'
import { FACTORY_V2_VERIFICATION } from './factories/v2/FactoryV2'
import { MAIN_MODULE_V2_VERIFICATION } from './factories/v2/MainModuleV2'
import { MAIN_MODULE_UPGRADABLE_V2_VERIFICATION } from './factories/v2/MainModuleUpgradableV2'
import { SEQUENCE_UTILS_V1_VERIFICATION } from './factories/v1/SequenceUtilsV1'
import { FactoryV2, GuestModuleV2, MainModuleUpgradableV2, MainModuleV2, SequenceUtilsV2 } from './factories/v2'
import { FACTORY_V2_VERIFICATION, WALLET_CREATION_CODE } from './factories/v2/FactoryV2'
import { GUEST_MODULE_V2_VERIFICATION } from './factories/v2/GuestModuleV2'
import { MAIN_MODULE_UPGRADABLE_V2_VERIFICATION } from './factories/v2/MainModuleUpgradableV2'
import { MAIN_MODULE_V2_VERIFICATION } from './factories/v2/MainModuleV2'
import { SEQUENCE_UTILS_V2_VERIFICATION } from './factories/v2/SequenceUtilsV2'
import { ORDERBOOK_VERIFICATION, Orderbook } from './factories/orderbook/Orderbook'
import { deployDeveloperMultisig } from './wallets/DeveloperMultisig'
import { deployGuard } from './wallets/Guard'
import {
TUBPROXY_VERIFICATION,
TransparentUpgradeableBeaconProxy
} from './factories/token_library/TransparentUpgradeableBeaconProxy'
import { UPGRADEABLEBEACON_VERIFICATION, UpgradeableBeacon } from './factories/token_library/UpgradeableBeacon'

dotenvConfig()

const { RPC_URL, DEPLOYER_PRIVATE_KEY, NETWORK_NAME, VERIFIER_API_URL, VERIFIER_API_KEY } = process.env
interface Logger {
log(message: string): void
error(message: string): void
}

const { RPC_URL, DEPLOYER_PRIVATE_KEY, NETWORK_NAME, VERIFIER_API_URL, VERIFIER_API_KEY, GAS_LIMIT, GAS_PRICE } = process.env

export const deployContracts = async (rpcUrl: string, deployerPK: string, networkName?: string): Promise<void> => {
const prompt = ora()
const prompt = ora() as Ora & Logger
prompt.log = (message: string) => {
// Log a message and keep spinner running
const currentText = prompt.text
prompt.info(message)
prompt.start(currentText)
}
prompt.error = prompt.fail

const provider = new JsonRpcProvider(rpcUrl)
const signer = new ethers.Wallet(deployerPK, provider)
provider.getSigner = () => signer as unknown as ethers.providers.JsonRpcSigner

prompt.info(`Network Name: ${networkName}`)
prompt.info(`Chain Id: ${(await provider.getNetwork()).chainId}`)
prompt.info(`Gas price: ${await provider.getGasPrice()}`)
prompt.info(`Local Deployer Address: ${await signer.getAddress()}`)
prompt.info(`Local Deployer Balance: ${await signer.getBalance()}`)

// v1

prompt.start(`Deploying V1 contracts\n`)

const txParams = {
// gasLimit: BigNumber.from(7500000),
gasLimit: await provider.getBlock('latest').then(b => b.gasLimit.mul(4).div(10))
gasPrice: GAS_PRICE ? BigNumber.from(GAS_PRICE) : undefined, // Automated gas price
// gasPrice: (await provider.getGasPrice()).mul(3).div(2), // 1.5x gas price
gasLimit: GAS_LIMIT ? BigNumber.from(GAS_LIMIT) : await provider.getBlock('latest').then(b => b.gasLimit.mul(4).div(10))
// gasPrice: BigNumber.from(10).pow(8).mul(16)
}

const universalDeployer = new deployers.UniversalDeployer(signer, console)
// v1

prompt.start(`Deploying V1 contracts\n`)

const universalDeployer = new deployers.UniversalDeployer(signer, prompt)

const walletFactoryV1 = await universalDeployer.deploy('WalletFactory', FactoryV1, 0, txParams)
const mainModuleV1 = await universalDeployer.deploy('MainModule', MainModuleV1, 0, txParams, walletFactoryV1.address)
Expand All @@ -80,7 +106,8 @@ export const deployContracts = async (rpcUrl: string, deployerPK: string, networ
'Guard V1',
'0x596aF90CecdBF9A768886E771178fd5561dD27Ab',
mainModuleV1.address,
'0xc99c1ab359199e4dcbd4603e9b2956d5681241ceb286359cf6a647ca56e6e128'
'0xc99c1ab359199e4dcbd4603e9b2956d5681241ceb286359cf6a647ca56e6e128',
txParams
)

prompt.succeed(`Deployed V1 contracts\n`)
Expand All @@ -89,7 +116,7 @@ export const deployContracts = async (rpcUrl: string, deployerPK: string, networ

prompt.start(`Deploying V2 contracts\n`)

const singletonDeployer = new deployers.SingletonDeployer(signer, console) //, undefined, BigNumber.from('30000000000000000'))
const singletonDeployer = new deployers.SingletonDeployer(signer, prompt) //, undefined, BigNumber.from('30000000000000000'))

const walletFactoryV2 = await singletonDeployer.deploy('Factory', FactoryV2, 0, txParams)
const mainModuleUpgradeableV2 = await singletonDeployer.deploy('MainModuleUpgradable', MainModuleUpgradableV2, 0, txParams)
Expand All @@ -109,21 +136,78 @@ export const deployContracts = async (rpcUrl: string, deployerPK: string, networ
'Guard V2',
'0x761f5e29944D79d76656323F106CF2efBF5F09e9',
mainModuleV2.address,
'0x6e2f52838722eda7d569b52db277d0d87d36991a6aa9b9657ef9d8f09b0c33f4'
'0x6e2f52838722eda7d569b52db277d0d87d36991a6aa9b9657ef9d8f09b0c33f4',
txParams
)

prompt.succeed(`Deployed V2 contracts\n`)

// Sequence development multisig

prompt.start(`Deploying Sequence development multisig\n`)

const v2WalletContext = {
version: 2,
factory: walletFactoryV2.address,
mainModule: mainModuleV2.address,
mainModuleUpgradable: mainModuleUpgradeableV2.address,
guestModule: guestModuleV2.address,
sequenceUtils: sequenceUtilsV2.address,
walletCreationCode: WALLET_CREATION_CODE
}
const developerMultisig = await deployDeveloperMultisig(signer, v2WalletContext, txParams)
prompt.succeed(`Deployed Sequence development multisig\n`)

// Marketplace contracts

prompt.start(`Deploying Marketplace contracts\n`)
const orderbook = await singletonDeployer.deploy('Orderbook', Orderbook, 0, txParams)
prompt.succeed(`Deployed Marketplace contracts\n`)

// Contracts library

prompt.start(`Deploying Library contracts\n`)
const erc20MinterFactory = await singletonDeployer.deploy(
'ERC20MinterFactory',
ERC20MinterFactory,
0,
txParams,
developerMultisig.address
)
const erc721MinterFactory = await singletonDeployer.deploy(
'ERC721MinterFactory',
ERC721MinterFactory,
0,
txParams,
developerMultisig.address
)
const erc721SaleFactory = await singletonDeployer.deploy(
'ERC721SaleFactory',
ERC721SaleFactory,
0,
txParams,
developerMultisig.address
)
const erc1155MinterFactory = await singletonDeployer.deploy(
'ERC1155MinterFactory',
ERC1155MinterFactory,
0,
txParams,
developerMultisig.address
)
const erc1155SaleFactory = await singletonDeployer.deploy(
'ERC1155SaleFactory',
ERC1155SaleFactory,
0,
txParams,
developerMultisig.address
)
prompt.succeed(`Deployed Library contracts\n`)

// Output addresses

prompt.start(`Writing deployment information to output_${networkName}.json\n`)
fs.writeFileSync(
void writeFile(
`./output_${networkName}.json`,
JSON.stringify(
[
Expand All @@ -140,7 +224,13 @@ export const deployContracts = async (rpcUrl: string, deployerPK: string, networ
{ name: 'RequireFreshSignerLibV1', address: requireFreshSignerLibV1.address },
{ name: 'GuardV2', address: '0x761f5e29944D79d76656323F106CF2efBF5F09e9' },
{ name: 'GuardV1', address: '0x596aF90CecdBF9A768886E771178fd5561dD27Ab' },
{ name: 'DeveloperMultisig', address: developerMultisig.address },
{ name: 'Orderbook', address: orderbook.address },
{ name: 'ERC20MinterFactory', address: erc20MinterFactory.address },
{ name: 'ERC721MinterFactory', address: erc721MinterFactory.address },
{ name: 'ERC721SaleFactory', address: erc721SaleFactory.address },
{ name: 'ERC1155MinterFactory', address: erc1155MinterFactory.address },
{ name: 'ERC1155SaleFactory', address: erc1155SaleFactory.address }
],
null,
2
Expand All @@ -156,7 +246,7 @@ export const deployContracts = async (rpcUrl: string, deployerPK: string, networ
return
}

const verifier = new verifiers.EtherscanVerifier(VERIFIER_API_KEY, VERIFIER_API_URL, console)
const verifier = new verifiers.EtherscanVerifier(VERIFIER_API_KEY, VERIFIER_API_URL, prompt)
const waitForSuccess = true // One at a time

const { defaultAbiCoder } = ethers.utils
Expand Down Expand Up @@ -210,6 +300,84 @@ export const deployContracts = async (rpcUrl: string, deployerPK: string, networ
prompt.start('Verifying Marketplace contracts\n')
await verifier.verifyContract(orderbook.address, { ...ORDERBOOK_VERIFICATION, waitForSuccess })
prompt.succeed('Verified Marketplace contracts\n')

// Library contracts

prompt.start(`Verifying Library contracts\n`)
// Factories
await verifier.verifyContract(erc20MinterFactory.address, {
...ERC20MINTERFACTORY_VERIFICATION,
waitForSuccess,
constructorArgs: defaultAbiCoder.encode(['address'], [developerMultisig.address])
})
await verifier.verifyContract(erc721MinterFactory.address, {
...ERC721MINTERFACTORY_VERIFICATION,
waitForSuccess,
constructorArgs: defaultAbiCoder.encode(['address'], [developerMultisig.address])
})
await verifier.verifyContract(erc721SaleFactory.address, {
...ERC721SALEFACTORY_VERIFICATION,
waitForSuccess,
constructorArgs: defaultAbiCoder.encode(['address'], [developerMultisig.address])
})
await verifier.verifyContract(erc1155MinterFactory.address, {
...ERC1155MINTERFACTORY_VERIFICATION,
waitForSuccess,
constructorArgs: defaultAbiCoder.encode(['address'], [developerMultisig.address])
})
await verifier.verifyContract(erc1155SaleFactory.address, {
...ERC1155SALEFACTORY_VERIFICATION,
waitForSuccess,
constructorArgs: defaultAbiCoder.encode(['address'], [developerMultisig.address])
})
// Also deploy the TUBProxy for verification purposes
const tubProxy = await singletonDeployer.deploy(
'TransparentUpgradeableBeaconProxy',
TransparentUpgradeableBeaconProxy,
0,
txParams
)
// Token contracts deployed by the factories
const beacon = new UpgradeableBeacon(signer)
await verifier.verifyContract(await beacon.attach(await erc20MinterFactory.beacon()).implementation(), {
...ERC20MINTERFACTORY_VERIFICATION,
contractToVerify: 'src/tokens/ERC20/presets/minter/ERC20TokenMinter.sol:ERC20TokenMinter',
waitForSuccess
})
await verifier.verifyContract(await beacon.attach(await erc721MinterFactory.beacon()).implementation(), {
...ERC721MINTERFACTORY_VERIFICATION,
contractToVerify: 'src/tokens/ERC721/presets/minter/ERC721TokenMinter.sol:ERC721TokenMinter',
waitForSuccess
})
await verifier.verifyContract(await beacon.attach(await erc721SaleFactory.beacon()).implementation(), {
...ERC721SALEFACTORY_VERIFICATION,
contractToVerify: 'src/tokens/ERC721/presets/sale/ERC721Sale.sol:ERC721Sale',
waitForSuccess
})
await verifier.verifyContract(await beacon.attach(await erc1155MinterFactory.beacon()).implementation(), {
...ERC1155MINTERFACTORY_VERIFICATION,
contractToVerify: 'src/tokens/ERC1155/presets/minter/ERC1155TokenMinter.sol:ERC1155TokenMinter',
waitForSuccess
})
const erc1155SaleBeacon = await erc1155SaleFactory.beacon()
const erc1155SaleImplementation = await beacon.attach(erc1155SaleBeacon).implementation()
await verifier.verifyContract(erc1155SaleImplementation, {
...ERC1155SALEFACTORY_VERIFICATION,
contractToVerify: 'src/tokens/ERC1155/presets/sale/ERC1155Sale.sol:ERC1155Sale',
waitForSuccess
})
// Proxies
await verifier.verifyContract(erc1155SaleBeacon, {
...UPGRADEABLEBEACON_VERIFICATION,
waitForSuccess,
constructorArgs: defaultAbiCoder.encode(['address'], [erc1155SaleImplementation])
})
await verifier.verifyContract(tubProxy.address, {
...TUBPROXY_VERIFICATION,
waitForSuccess
})

prompt.succeed(`Verified Library contracts\n`)
}

const main = async () => {
Expand Down
Loading

0 comments on commit 7d3b4a9

Please sign in to comment.