Skip to content

Commit

Permalink
Merge branch 'master' into feat/deploy-zksync
Browse files Browse the repository at this point in the history
  • Loading branch information
JhChoy committed May 17, 2024
2 parents 4c11417 + 7a999c4 commit 8b589e5
Show file tree
Hide file tree
Showing 13 changed files with 232 additions and 2,585 deletions.
45 changes: 29 additions & 16 deletions deploy/BookManager.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,55 @@
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import { DeployFunction } from 'hardhat-deploy/types'
import { getChain, isDevelopmentNetwork } from '@nomicfoundation/hardhat-viem/internal/chains'
import { deployWithVerify } from '../utils'
import { deployCreate3WithVerify, deployWithVerify } from '../utils'
import { base } from 'viem/chains'
import { Address } from 'viem'

const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts, network } = hre
const { deployer } = await getNamedAccounts()
const deployer = (await getNamedAccounts())['deployer'] as Address
const chain = await getChain(network.provider)

let bookLibraryAddress = (await deployments.getOrNull('Book'))?.address
if (!bookLibraryAddress) {
bookLibraryAddress = await deployWithVerify(hre, 'Book')
bookLibraryAddress = await deployWithVerify(hre, 'Book', [])
}

if (await deployments.getOrNull('BookManager')) {
return
}

let args: any[] = []
let owner: Address = '0x'
let defaultProvider: Address = '0x'
if (chain.testnet || isDevelopmentNetwork(chain.id)) {
args = [deployer, deployer, 'baseURI', 'contractURI', 'Clober Orderbook Maker Order', 'CLOB-ORDER']
owner = defaultProvider = deployer
} else if (chain.id === base.id) {
args = [
'0xfb976Bae0b3Ef71843F1c6c63da7Df2e44B3836d', // Safe
'0xfc5899d93df81ca11583bee03865b7b13ce093a7', // Treasury
`https://clober.io/api/nft/chains/${chain.id}/orders/`,
`https://clober.io/api/contract/chains/${chain.id}`,
'Clober Orderbook Maker Order',
'CLOB-ORDER',
]
owner = '0xfb976Bae0b3Ef71843F1c6c63da7Df2e44B3836d' // Safe
defaultProvider = '0xfc5899d93df81ca11583bee03865b7b13ce093a7' // Treasury
} else {
throw new Error('Unknown chain')
}

await deployWithVerify(hre, 'BookManager', args, {
Book: bookLibraryAddress,
})
const entropy = 256n

await deployCreate3WithVerify(
deployer,
entropy,
'BookManager',
[
owner,
defaultProvider,
`https://clober.io/api/nft/chains/${chain.id}/orders/`,
`https://clober.io/api/contract/chains/${chain.id}`,
'Clober Orderbook Maker Order',
'CLOB-ORDER',
],
{
libraries: {
Book: bookLibraryAddress,
},
},
)
}

deployFunction.tags = ['BookManager']
Expand Down
26 changes: 13 additions & 13 deletions deployments/421614/Book.json

Large diffs are not rendered by default.

1,173 changes: 5 additions & 1,168 deletions deployments/421614/BookManager.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

186 changes: 0 additions & 186 deletions deployments/421614/solcInputs/976d3b92ad3c0d443b76ccea53a02341.json

This file was deleted.

28 changes: 14 additions & 14 deletions deployments/8453/Book.json

Large diffs are not rendered by default.

1,169 changes: 3 additions & 1,166 deletions deployments/8453/BookManager.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ for (const [networkName, networkInfo] of Object.entries(networkInfos)) {

const SKIP_LOAD = process.env.SKIP_LOAD === 'true'

// Prevent to load scripts before compilation and typechain
// Prevent to load scripts before compilation
if (!SKIP_LOAD) {
const tasksPath = path.join(__dirname, 'task')
fs.readdirSync(tasksPath)
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"declaration": true,
"typeRoots": ["./node_modules/@types"],
"types": ["@nomiclabs/hardhat-ethers", "@nomiclabs/hardhat-waffle", "hardhat-deploy"]
},
}
}
19 changes: 13 additions & 6 deletions utils/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,31 @@ export const verify = async (contractAddress: string, args: any[]) => {
export const deployWithVerify = async (
hre: HardhatRuntimeEnvironment,
name: string,
args?: any[],
libraries?: any,
proxy?: boolean,
args: any[],
options?: {
libraries?: any
proxy?: boolean
contract?: string
},
) => {
if (!options) {
options = {}
}
const { deployer } = await hre.getNamedAccounts()
const deployedAddress = (
await hre.deployments.deploy(name, {
from: deployer,
args: args,
log: true,
libraries: libraries,
proxy: proxy,
libraries: options.libraries,
proxy: options.proxy,
contract: options.contract,
})
).address

try {
await hre.run('verify:verify', {
address: proxy ? await getImplementationAddress(hre.network.provider, deployedAddress) : deployedAddress,
address: options.proxy ? await getImplementationAddress(hre.network.provider, deployedAddress) : deployedAddress,
constructorArguments: args,
})
} catch (e) {
Expand Down
138 changes: 138 additions & 0 deletions utils/createX.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import {
Address,
decodeEventLog,
encodeAbiParameters,
encodeDeployData,
getContract,
Hex,
keccak256,
parseAbi,
toHex,
} from 'viem'
import { getHRE, liveLog, sleep } from './misc'
import { Libraries } from 'hardhat-deploy/dist/types'

export const CreateXFactoryAddress = '0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed'

export const CreateXFactoryAbi = parseAbi([
'error FailedContractCreation(address)',
'error FailedContractInitialisation(address,bytes)',
'error FailedEtherTransfer(address,bytes)',
'error InvalidNonceValue(address)',
'error InvalidSalt(address)',
'event ContractCreation(address indexed,bytes32 indexed)',
'event ContractCreation(address indexed)',
'event Create3ProxyContractCreation(address indexed,bytes32 indexed)',
'function computeCreate2Address(bytes32,bytes32) view returns (address)',
'function computeCreate2Address(bytes32,bytes32,address) pure returns (address)',
'function computeCreate3Address(bytes32,address) pure returns (address)',
'function computeCreate3Address(bytes32) view returns (address)',
'function computeCreateAddress(uint256) view returns (address)',
'function computeCreateAddress(address,uint256) view returns (address)',
'function deployCreate(bytes) payable returns (address)',
'function deployCreate2(bytes32,bytes) payable returns (address)',
'function deployCreate2(bytes) payable returns (address)',
'function deployCreate2AndInit(bytes32,bytes,bytes,(uint256,uint256),address) payable returns (address)',
'function deployCreate2AndInit(bytes,bytes,(uint256,uint256)) payable returns (address)',
'function deployCreate2AndInit(bytes,bytes,(uint256,uint256),address) payable returns (address)',
'function deployCreate2AndInit(bytes32,bytes,bytes,(uint256,uint256)) payable returns (address)',
'function deployCreate2Clone(bytes32,address,bytes) payable returns (address)',
'function deployCreate2Clone(address,bytes) payable returns (address)',
'function deployCreate3(bytes) payable returns (address)',
'function deployCreate3(bytes32,bytes) payable returns (address)',
'function deployCreate3AndInit(bytes32,bytes,bytes,(uint256,uint256)) payable returns (address)',
'function deployCreate3AndInit(bytes,bytes,(uint256,uint256)) payable returns (address)',
'function deployCreate3AndInit(bytes32,bytes,bytes,(uint256,uint256),address) payable returns (address)',
'function deployCreate3AndInit(bytes,bytes,(uint256,uint256),address) payable returns (address)',
'function deployCreateAndInit(bytes,bytes,(uint256,uint256)) payable returns (address)',
'function deployCreateAndInit(bytes,bytes,(uint256,uint256),address) payable returns (address)',
'function deployCreateClone(address,bytes) payable returns (address)',
])

export const deployCreate3WithVerify = async (
deployer: Address,
entropy: bigint,
name: string,
args: any[],
options?: {
libraries?: Libraries
contract?: string
},
): Promise<Address> => {
if (entropy >= 2n ** 88n) {
throw new Error('Entropy too large')
}
liveLog('Create3 deploying', name, 'with entropy', entropy.toString(16))
if (!options) {
options = {}
}
const hre = getHRE()

const artifact = await hre.artifacts.readArtifact(options.contract ? options.contract : name)

let bytecode = artifact.bytecode as Hex
if (options?.libraries) {
for (const [libraryName, libraryAddress] of Object.entries(options.libraries)) {
const libArtifact = await hre.artifacts.readArtifact(libraryName)
const key =
'__\\$' + keccak256(toHex(libArtifact.sourceName + ':' + libArtifact.contractName)).slice(2, 36) + '\\$__'
bytecode = bytecode.replace(new RegExp(key, 'g'), libraryAddress.slice(2)) as Hex
}
}

const initcode = encodeDeployData({ abi: artifact.abi, bytecode, args })

const salt = (deployer + '00' + entropy.toString(16).padStart(22, '0')) as Hex

const createXFactory = getContract({
abi: CreateXFactoryAbi,
address: CreateXFactoryAddress,
client: await hre.viem.getWalletClient(deployer),
})
const publicClient = await hre.viem.getPublicClient()

const guardedSalt = keccak256(encodeAbiParameters([{ type: 'address' }, { type: 'bytes32' }], [deployer, salt]))
let address: Address = await createXFactory.read.computeCreate3Address([guardedSalt])
liveLog('Computed address', address)

const remoteBytecode = await publicClient.getBytecode({ address })
let txHash: Hex = '0x'
if (remoteBytecode && remoteBytecode.length > 0) {
liveLog('Contract already deployed at', address, '\n')
} else {
txHash = await createXFactory.write.deployCreate3([salt, initcode])
const receipt = await publicClient.getTransactionReceipt({ hash: txHash }).catch(async () => {
await sleep(500)
return publicClient.getTransactionReceipt({ hash: txHash })
})
const event = receipt.logs
.filter((log) => log.address.toLowerCase() === CreateXFactoryAddress.toLowerCase())
.map((log) => decodeEventLog({ abi: createXFactory.abi, data: log.data, topics: log.topics }))
.find((log) => log.eventName === 'ContractCreation')
if (!event) {
throw new Error('Contract creation event not found')
}
address = event.args[0]

liveLog('Contract created at', address, '\n')
}

try {
await hre.run('verify:verify', {
address: address,
constructorArguments: args,
})
} catch (e) {
console.log(e)
}

await hre.deployments.save(name, {
address: address,
abi: artifact.abi,
transactionHash: txHash,
args,
bytecode,
})

return address
}
1 change: 1 addition & 0 deletions utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './contract'
export * from './createX'
export * from './misc'

0 comments on commit 8b589e5

Please sign in to comment.