Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ops/docker/Dockerfile.aa_deployer
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ WORKDIR /opt/optimism/

COPY --from=builder /optimism/*.json /optimism/yarn.lock ./
COPY --from=builder /optimism/node_modules ./node_modules
COPY --from=builder /optimism/packages/boba/bundler/packages/sdk ./packages/boba/bundler/packages/sdk

WORKDIR /opt/optimism/packages/contracts
COPY --from=builder /optimism/packages/contracts/dist ./dist
Expand Down
2 changes: 2 additions & 0 deletions ops/docker/Dockerfile.packages
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ COPY packages/boba/ve-boba/package.json ./packages/boba/ve-boba/package.json
COPY packages/boba/bobalink/package.json ./packages/boba/bobalink/package.json
COPY packages/boba/teleportation/package.json ./packages/boba/teleportation/package.json
COPY packages/boba/account-abstraction/package.json ./packages/boba/account-abstraction/package.json
COPY packages/boba/bundler/packages/sdk/package.json ./packages/boba/bundler/packages/sdk/package.json

FROM base as builder
WORKDIR /opt/optimism
Expand Down Expand Up @@ -94,6 +95,7 @@ COPY --from=builder /opt/optimism/node_modules ./node_modules
COPY --from=builder /opt/optimism/packages/sdk/dist ./packages/sdk/dist
COPY --from=builder /opt/optimism/packages/core-utils/dist ./packages/core-utils/dist
COPY --from=builder /opt/optimism/packages/common-ts/dist ./packages/common-ts/dist
COPY --from=builder /opt/optimism/packages/boba/bundler/packages/sdk ./packages/boba/bundler/packages/sdk

# some packages need to access the bytecode of the contracts and deployment files
COPY --from=builder /opt/optimism/packages/contracts ./packages/contracts
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"packages": [
"packages/*",
"packages/boba/*",
"packages/boba/bundler/packages/*",
"l2geth",
"integration-tests",
"specs",
Expand Down
137 changes: 77 additions & 60 deletions packages/boba/account-abstraction/deploy/1-deploy-helper.ts
Original file line number Diff line number Diff line change
@@ -1,81 +1,98 @@
import { DeployFunction } from 'hardhat-deploy/types'
import { DeployFunction, DeploymentSubmission } from 'hardhat-deploy/types'
import { ethers } from 'hardhat'
import { Contract, ContractFactory } from 'ethers'
import BundlerHelperJson from '../artifacts/contracts/bundler/BundlerHelper.sol/BundlerHelper.json'
import { DeterministicDeployer } from '@account-abstraction/sdk/src/DeterministicDeployer'

const sleep = async (ms: number): Promise<void> => {
return new Promise<void>((resolve) => {
setTimeout(() => {
resolve(null)
}, ms)
})
return new Promise<void>((resolve) => {
setTimeout(() => {
resolve(null)
}, ms)
})
}

const hexStringEquals = (stringA: string, stringB: string): boolean => {
if (!ethers.utils.isHexString(stringA)) {
throw new Error(`input is not a hex string: ${stringA}`)
}

const hexStringEquals = (stringA: string, stringB: string): boolean => {
if (!ethers.utils.isHexString(stringA)) {
throw new Error(`input is not a hex string: ${stringA}`)
}
if (!ethers.utils.isHexString(stringB)) {
throw new Error(`input is not a hex string: ${stringB}`)
}

if (!ethers.utils.isHexString(stringB)) {
throw new Error(`input is not a hex string: ${stringB}`)
}
return stringA.toLowerCase() === stringB.toLowerCase()
}

return stringA.toLowerCase() === stringB.toLowerCase()
}
const waitUntilTrue = async (
check: () => Promise<boolean>,
opts: {
retries?: number
delay?: number
} = {}
) => {
opts.retries = opts.retries || 100
opts.delay = opts.delay || 5000

const waitUntilTrue = async (
check: () => Promise<boolean>,
opts: {
retries?: number
delay?: number
} = {}
) => {
opts.retries = opts.retries || 100
opts.delay = opts.delay || 5000

let retries = 0
while (!(await check())) {
if (retries > opts.retries) {
throw new Error(`check failed after ${opts.retries} attempts`)
}
retries++
await sleep(opts.delay)
let retries = 0
while (!(await check())) {
if (retries > opts.retries) {
throw new Error(`check failed after ${opts.retries} attempts`)
}
retries++
await sleep(opts.delay)
}
}

export const registerBobaAddress = async (
addressManager: any,
name: string,
address: string
): Promise<void> => {
export const registerBobaAddress = async (
addressManager: any,
name: string,
address: string
): Promise<void> => {
console.log("AddressManager address:",addressManager.address)

console.log("AddressManager address:",addressManager.address)
const currentAddress = await addressManager.getAddress(name)
if (address === currentAddress) {
console.log(
`✓ Not registering address for ${name} because it's already been correctly registered`
)
return
}

const currentAddress = await addressManager.getAddress(name)
if (address === currentAddress) {
console.log(
`✓ Not registering address for ${name} because it's already been correctly registered`
)
return
}
console.log(`Registering address for ${name} to ${address}...`)
await addressManager.setAddress(name, address)

console.log(`Registering address for ${name} to ${address}...`)
await addressManager.setAddress(name, address)
console.log(`Waiting for registration to reflect on-chain...`)
await waitUntilTrue(async () => {
return hexStringEquals(await addressManager.getAddress(name), address)
})

console.log(`Waiting for registration to reflect on-chain...`)
await waitUntilTrue(async () => {
return hexStringEquals(await addressManager.getAddress(name), address)
})
console.log(`✓ Registered address for ${name}`)
}

console.log(`✓ Registered address for ${name}`)
}
let Factory__BundlerHelper: ContractFactory

const deployFn: DeployFunction = async (hre) => {
const BundlerHelper = await hre.deployments.deploy('BundlerHelper', {
from: (hre as any).deployConfig.deployer_l2.address,
args: [],
log: true,
deterministicDeployment: true
})
await registerBobaAddress( (hre as any).deployConfig.addressManager, 'Boba_BundlerHelper', BundlerHelper.address )
Factory__BundlerHelper = new ContractFactory(
BundlerHelperJson.abi,
BundlerHelperJson.bytecode,
(hre as any).deployConfig.deployer_l2
)

// specify network here to deploy on mainnet/goerli or other networks
// for example: const dep = new DeterministicDeployer((hre as any).deployConfig.l2Provider, (hre as any).deployConfig.deployer_l2, "boba_mainnet")
// third parameter for DeterministicDeployer is network
const dep = new DeterministicDeployer((hre as any).deployConfig.l2Provider, (hre as any).deployConfig.deployer_l2, 'local')
const BundlerHelperAddress = await dep.deterministicDeploy(Factory__BundlerHelper.bytecode)
console.log('Deployed BundlerHelper at', BundlerHelperAddress)

const BundlerHelperDeploymentSubmission: DeploymentSubmission = {
address: BundlerHelperAddress,
abi: BundlerHelperJson.abi
}
await hre.deployments.save('BundlerHelper', BundlerHelperDeploymentSubmission)

await registerBobaAddress((hre as any).deployConfig.addressManager, 'Boba_BundlerHelper', BundlerHelperAddress )
}

export default deployFn
Expand Down
45 changes: 18 additions & 27 deletions packages/boba/account-abstraction/deploy/2-deploy_entrypoint.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,28 @@
import { DeployFunction } from 'hardhat-deploy/types'
import { DeployFunction, DeploymentSubmission } from 'hardhat-deploy/types'
import { ethers } from 'hardhat'
import { Contract, ContractFactory } from 'ethers'
import { registerBobaAddress } from './1-deploy-helper'
import EntryPointJson from '../artifacts/contracts/core/EntryPoint.sol/EntryPoint.json'
import { DeterministicDeployer } from '@account-abstraction/sdk/src/DeterministicDeployer'

// const UNSTAKE_DELAY_SEC = 100
// const PAYMASTER_STAKE = ethers.utils.parseEther('1')
let Factory__EntryPoint: ContractFactory

// deploy entrypoint - but only on debug network..
const deployFn: DeployFunction = async (hre) => {
// first verify if already deployed:
try {
await hre.deployments.deploy(
'EntryPoint', {
from: ethers.constants.AddressZero,
args: [],
deterministicDeployment: true,
log: true
})
Factory__EntryPoint = new ContractFactory(
EntryPointJson.abi,
EntryPointJson.bytecode,
(hre as any).deployConfig.deployer_l2
)
const dep = new DeterministicDeployer((hre as any).deployConfig.l2Provider, (hre as any).deployConfig.deployer_l2, 'local')
const EntryPointAddress = await dep.deterministicDeploy(Factory__EntryPoint.bytecode)
console.log('Deployed EntryPoint at', EntryPointAddress)

// already deployed. do nothing.
return
} catch (e) {
const EntryPointDeploymentSubmission: DeploymentSubmission = {
address: EntryPointAddress,
abi: EntryPointJson.abi
}

const EntryPoint = await hre.deployments.deploy(
'EntryPoint', {
from: (hre as any).deployConfig.deployer_l2.address,
args: [],
gasLimit: 4e6,
deterministicDeployment: true,
log: true
})

await registerBobaAddress( (hre as any).deployConfig.addressManager, 'Boba_EntryPoint', EntryPoint.address )
await hre.deployments.save('EntryPoint', EntryPointDeploymentSubmission)
await registerBobaAddress( (hre as any).deployConfig.addressManager, 'Boba_EntryPoint', EntryPointAddress )
}

export default deployFn
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,44 @@
import { DeployFunction } from 'hardhat-deploy/types'
import { DeployFunction, DeploymentSubmission } from 'hardhat-deploy/types'
import { ethers } from 'hardhat'
import { Contract, ContractFactory } from 'ethers'
import { registerBobaAddress } from './1-deploy-helper'
import BobaDepositPaymasterJson from '../artifacts/contracts/samples/BobaDepositPaymaster.sol/BobaDepositPaymaster.json'
import { DeterministicDeployer } from '@account-abstraction/sdk/src/DeterministicDeployer'

let Factory__BobaDepositPaymaster: ContractFactory

const deployFn: DeployFunction = async (hre) => {
Factory__BobaDepositPaymaster = new ContractFactory(
BobaDepositPaymasterJson.abi,
BobaDepositPaymasterJson.bytecode,
(hre as any).deployConfig.deployer_l2
)
const entryPoint = await hre.deployments.getOrNull('EntryPoint')
console.log(`EntryPoint is located at: ${entryPoint.address}`)
const ethPriceOracle = await (hre as any).deployConfig.addressManager.getAddress('FeedRegistry')
console.log(`Eth Price Oracle is located at: ${ethPriceOracle}`)
const entryPointFromAM = await (hre as any).deployConfig.addressManager.getAddress('Boba_EntryPoint')
if (entryPoint.address == entryPointFromAM) {
const BobaDepositPaymaster = await hre.deployments.deploy(
'BobaDepositPaymaster', {
from: (hre as any).deployConfig.deployer_l2.address,
args: [entryPoint.address, ethPriceOracle],
gasLimit: 4e6,
deterministicDeployment: false,
log: true
})
if (entryPoint.address.toLowerCase() === entryPointFromAM.toLowerCase()) {
const bobaDepositPaymasterConstructorArgs = ethers.utils.defaultAbiCoder.encode(
["address", "address"],
[entryPoint.address, ethPriceOracle]
)
const bobaDepositPaymasterCreationCode = ethers.utils.solidityPack(
["bytes", "bytes"],
[Factory__BobaDepositPaymaster.bytecode, bobaDepositPaymasterConstructorArgs]
)

const dep = new DeterministicDeployer((hre as any).deployConfig.l2Provider, (hre as any).deployConfig.deployer_l2, 'local')
const BobaDepositPaymasterAddress = await dep.deterministicDeploy(bobaDepositPaymasterCreationCode)
console.log('Boba Deposit Paymaster at', BobaDepositPaymasterAddress)

const BobaDepositPaymasterDeploymentSubmission: DeploymentSubmission = {
address: BobaDepositPaymasterAddress,
abi: BobaDepositPaymasterJson.abi
}
await hre.deployments.save('BobaDepositPaymaster', BobaDepositPaymasterDeploymentSubmission)

await registerBobaAddress( (hre as any).deployConfig.addressManager, 'BobaDepositPaymaster', BobaDepositPaymaster.address )
await registerBobaAddress( (hre as any).deployConfig.addressManager, 'BobaDepositPaymaster', BobaDepositPaymasterAddress )
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { DeployFunction } from 'hardhat-deploy/types'
import { DeployFunction, DeploymentSubmission } from 'hardhat-deploy/types'
import { ethers } from 'hardhat'
import { Contract, ContractFactory } from 'ethers'
import { registerBobaAddress } from './1-deploy-helper'
import BobaVerifyingPaymasterJson from '../artifacts/contracts/samples/BobaVerifyingPaymaster.sol/BobaVerifyingPaymaster.json'
import { DeterministicDeployer } from '@account-abstraction/sdk/src/DeterministicDeployer'

let Factory__BobaVerifyingPaymaster: ContractFactory

const deployFn: DeployFunction = async (hre) => {
Factory__BobaVerifyingPaymaster = new ContractFactory(
BobaVerifyingPaymasterJson.abi,
BobaVerifyingPaymasterJson.bytecode,
(hre as any).deployConfig.deployer_l2
)
// use the sig verifying address
const verifyingSignerAddress = (hre as any).deployConfig.deployer_l2.address
console.log(`Verifying Signer is: ${verifyingSignerAddress}`)
Expand All @@ -14,17 +24,26 @@ const deployFn: DeployFunction = async (hre) => {
const bobaToken = await (hre as any).deployConfig.addressManager.getAddress('TK_L2BOBA')
console.log(`Boba is located at: ${bobaToken}`)
const entryPointFromAM = await (hre as any).deployConfig.addressManager.getAddress('Boba_EntryPoint')
if (entryPoint.address == entryPointFromAM) {
const BobaVerifyingPaymaster = await hre.deployments.deploy(
'BobaVerifyingPaymaster', {
from: (hre as any).deployConfig.deployer_l2.address,
args: [entryPoint.address, verifyingSignerAddress, bobaDepositPaymaster.address, bobaToken],
gasLimit: 4e6,
deterministicDeployment: false,
log: true
})
if (entryPoint.address.toLowerCase() === entryPointFromAM.toLowerCase()) {
const bobaVerifyingPaymasterConstructorArgs = ethers.utils.defaultAbiCoder.encode(
["address", "address","address", "address"],
[entryPoint.address, verifyingSignerAddress, bobaDepositPaymaster.address, bobaToken]
)
const bobaVerifyingPaymasterCreationCode = ethers.utils.solidityPack(
["bytes", "bytes"],
[Factory__BobaVerifyingPaymaster.bytecode, bobaVerifyingPaymasterConstructorArgs]
)
const dep = new DeterministicDeployer((hre as any).deployConfig.l2Provider, (hre as any).deployConfig.deployer_l2, 'local')
const BobaVerifyingPaymasterAddress = await dep.deterministicDeploy(bobaVerifyingPaymasterCreationCode)
console.log('Boba Verifying Paymaster at', BobaVerifyingPaymasterAddress)

const BobaVerifyingPaymasterDeploymentSubmission: DeploymentSubmission = {
address: BobaVerifyingPaymasterAddress,
abi: BobaVerifyingPaymasterJson.abi
}
await hre.deployments.save('BobaVerifyingPaymaster', BobaVerifyingPaymasterDeploymentSubmission)

await registerBobaAddress( (hre as any).deployConfig.addressManager, 'BobaVerifyingPaymaster', BobaVerifyingPaymaster.address )
await registerBobaAddress( (hre as any).deployConfig.addressManager, 'BobaVerifyingPaymaster', BobaVerifyingPaymasterAddress )
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/boba/account-abstraction/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"typechain": "^8.1.0"
},
"dependencies": {
"@account-abstraction/sdk": "0.2.3",
"@gnosis.pm/safe-contracts": "^1.3.0",
"@nomiclabs/hardhat-etherscan": "^3.1.0",
"@openzeppelin/contracts": "^4.2.0",
Expand Down
Loading