Skip to content

Commit

Permalink
fix: several bug fixes / improvements after optimism devnet deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
sam-goldman committed Dec 3, 2022
1 parent 54fc699 commit d7fff20
Show file tree
Hide file tree
Showing 14 changed files with 309 additions and 162 deletions.
9 changes: 9 additions & 0 deletions .changeset/blue-seahorses-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@chugsplash/contracts': patch
'@chugsplash/core': patch
'@chugsplash/demo': patch
'@chugsplash/executor': patch
'@chugsplash/plugins': patch
---

Several improvements / bug fixes discovered when deploying on Optimism's devnet.
2 changes: 1 addition & 1 deletion packages/contracts/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
DeterministicProxyOwnerArtifact,
} from './ifaces'

const owner = '0x1A3DAA6F487A480c1aD312b90FD0244871940b66'
export const owner = '0x1A3DAA6F487A480c1aD312b90FD0244871940b66'

const chugsplashRegistrySourceName = ChugSplashRegistryArtifact.sourceName
const chugsplashBootLoaderSourceName = ChugSplashBootLoaderArtifact.sourceName
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"dependencies": {
"@chugsplash/contracts": "^0.3.10",
"@eth-optimism/common-ts": "^0.6.7",
"@eth-optimism/contracts-bedrock": "^0.8.0",
"@eth-optimism/core-utils": "^0.9.1",
"@ethersproject/abstract-provider": "^5.7.0",
Expand Down
33 changes: 30 additions & 3 deletions packages/core/src/actions/execute.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { EXECUTOR_BOND_AMOUNT } from '@chugsplash/contracts'
import { ethers } from 'ethers'
import { Logger } from '@eth-optimism/common-ts'

import {
fromRawChugSplashAction,
Expand All @@ -17,8 +18,13 @@ export const executeTask = async (args: {
bundleId: string
bundle: ChugSplashActionBundle
executor: ethers.Signer
projectName: string
logger: Logger
}) => {
const { chugSplashManager, bundleId, bundle, executor } = args
const { chugSplashManager, bundleId, bundle, executor, projectName, logger } =
args

logger.info(`Preparing to execute the project...`)

const bundleState: ChugSplashBundleState = await chugSplashManager.bundles(
bundleId
Expand All @@ -29,20 +35,28 @@ export const executeTask = async (args: {
bundleState.status !== ChugSplashBundleStatus.APPROVED &&
bundleState.status !== ChugSplashBundleStatus.COMPLETED
) {
throw new Error(`Bundle is not approved or completed.`)
throw new Error(
`${projectName} cannot be executed. Current project status: ${bundleState.status}`
)
}

if (bundleState.status === ChugSplashBundleStatus.APPROVED) {
if (bundleState.status === ChugSplashBundleStatus.COMPLETED) {
logger.info(`Already executed: ${projectName}.`)
} else if (bundleState.status === ChugSplashBundleStatus.APPROVED) {
if (bundleState.selectedExecutor === ethers.constants.AddressZero) {
logger.info(`Claiming the bundle for project: ${projectName}`)
await (
await chugSplashManager.claimBundle({
value: EXECUTOR_BOND_AMOUNT,
})
).wait()
logger.info(`Claimed the bundle.`)
} else if (bundleState.selectedExecutor !== executorAddress) {
throw new Error(`Another executor has already claimed the bundle.`)
}

logger.info(`Setting the state variables...`)

// Execute actions that have not been executed yet.
let currActionsExecuted = bundleState.actionsExecuted.toNumber()

Expand Down Expand Up @@ -85,6 +99,10 @@ export const executeTask = async (args: {
currActionsExecuted += setStorageBatch.length
}

logger.info(
`State variables have been set. Deploying the implementation contracts...`
)

// Execute DeployImplementation actions in series. We execute them one by one since each one
// costs significantly more gas than a setStorage action (usually in the millions).
for (let i = currActionsExecuted; i < firstSetImplIndex; i++) {
Expand All @@ -97,8 +115,15 @@ export const executeTask = async (args: {
)
).wait()
currActionsExecuted += 1
logger.info(
`Deployed implementation contract: ${
currActionsExecuted - firstDeployImplIndex
}/${firstSetImplIndex - firstDeployImplIndex}`
)
}

logger.info('Linking proxies to the implementation contracts...')

if (currActionsExecuted === firstSetImplIndex) {
// Complete the bundle by executing all the SetImplementation actions in a single
// transaction.
Expand All @@ -111,5 +136,7 @@ export const executeTask = async (args: {
)
).wait()
}

logger.info(`Successfully executed: ${projectName}`)
}
}
60 changes: 54 additions & 6 deletions packages/core/src/languages/solidity/predeploys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,23 @@ import {
DeterministicProxyOwnerArtifact,
DETERMINISTIC_PROXY_OWNER_ADDRESS,
CHUGSPLASH_REGISTRY_ADDRESS,
owner,
} from '@chugsplash/contracts'
import { Logger } from '@eth-optimism/common-ts'
import { sleep } from '@eth-optimism/core-utils'

import { getChugSplashRegistry, getProxyOwner } from '../../utils'
import {
getChugSplashRegistry,
getProxyAt,
getProxyOwner,
hasCode,
} from '../../utils'

export const deployChugSplashPredeploys = async (
export const initializeChugSplash = async (
provider: ethers.providers.JsonRpcProvider,
deployer: ethers.Signer
deployer: ethers.Signer,
logger?: Logger
): Promise<void> => {
const owner = '0x1A3DAA6F487A480c1aD312b90FD0244871940b66'

// Deploy the root ChugSplashManager.
const ChugSplashManager = await doDeterministicDeploy(provider, {
signer: deployer,
Expand All @@ -45,6 +52,8 @@ export const deployChugSplashPredeploys = async (
args: CHUGSPLASH_CONSTRUCTOR_ARGS[ChugSplashManagerArtifact.sourceName],
})

logger?.info('Deployed ChugSplashManager.')

// Deploy the ChugSplashBootLoader.
const ChugSplashBootLoader = await doDeterministicDeploy(provider, {
signer: deployer,
Expand All @@ -55,6 +64,8 @@ export const deployChugSplashPredeploys = async (
salt: ethers.utils.solidityKeccak256(['string'], ['ChugSplashBootLoader']),
})

logger?.info('Deployed ChugSplashBootloader.')

// Make sure the addresses match, just in case.
assert(
ChugSplashBootLoader.address === CHUGSPLASH_BOOTLOADER_ADDRESS,
Expand All @@ -74,6 +85,7 @@ export const deployChugSplashPredeploys = async (
CHUGSPLASH_REGISTRY_PROXY_ADDRESS
)
).wait()
logger?.info('Initialized ChugSplashBootloader.')
} catch (err) {
if (
err.message.includes('Initializable: contract is already initialized')
Expand All @@ -95,6 +107,8 @@ export const deployChugSplashPredeploys = async (
args: CHUGSPLASH_CONSTRUCTOR_ARGS[ProxyArtifact.sourceName],
})

logger?.info('Deployed ChugSplashRegistry proxy.')

// Make sure the addresses match, just in case.
assert(
ChugSplashRegistryProxy.address === CHUGSPLASH_REGISTRY_PROXY_ADDRESS,
Expand All @@ -114,6 +128,8 @@ export const deployChugSplashPredeploys = async (
],
})

logger?.info('Deployed DeterministicProxyOwner.')

// Make sure the addresses match, just in case.
assert(
DeterministicProxyOwner.address === DETERMINISTIC_PROXY_OWNER_ADDRESS,
Expand All @@ -137,6 +153,8 @@ export const deployChugSplashPredeploys = async (
)
).wait()

logger?.info('Initialized ChugSplashRegistry proxy.')

// Make sure ownership of the ChugSplashRegistry's proxy has been transferred.
assert(
(await getProxyOwner(ChugSplashRegistryProxy)) === owner,
Expand All @@ -154,13 +172,17 @@ export const deployChugSplashPredeploys = async (
salt: ethers.utils.solidityKeccak256(['string'], ['DefaultAdapter']),
})

logger?.info('Deployed DefaultAdapter.')

// Make sure the addresses match, just in case.
assert(
DefaultAdapter.address === DEFAULT_ADAPTER_ADDRESS,
'DefaultAdapter address mismatch'
)

// Optionally initialize registry.
// Set the default proxy type on the registry. Note that `monitorChugSplashSetup` relies on the
// fact that this is the last transaction to setup ChugSplash. If this changes, we also change
// `monitorChugSplashSetup` to reflect this.
const ChugSplashRegistry = getChugSplashRegistry(deployer)
const adapter = await ChugSplashRegistry.adapters(ethers.constants.HashZero)
if (adapter === ethers.constants.AddressZero) {
Expand All @@ -171,6 +193,7 @@ export const deployChugSplashPredeploys = async (
)
).wait()
}
logger?.info('Finished deploying ChugSplash.')
}

export const getDeterministicFactoryAddress = async (
Expand Down Expand Up @@ -268,3 +291,28 @@ export const isContractDeployed = async (
): Promise<boolean> => {
return (await provider.getCode(address)) !== '0x'
}

export const monitorChugSplashSetup = async (
provider: ethers.providers.JsonRpcProvider
) => {
const signer = provider.getSigner()
const ChugSplashRegistry = getChugSplashRegistry(signer)

while (!(await hasCode(provider, ChugSplashRegistry.address))) {
await sleep(1000)
}

while (
owner !==
(await getProxyOwner(getProxyAt(signer, CHUGSPLASH_REGISTRY_PROXY_ADDRESS)))
) {
await sleep(1000)
}

while (
(await ChugSplashRegistry.adapters(ethers.constants.HashZero)) !==
DEFAULT_ADAPTER_ADDRESS
) {
await sleep(1000)
}
}
19 changes: 19 additions & 0 deletions packages/core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from '@chugsplash/contracts'

import { ParsedChugSplashConfig } from './config'
import { ChugSplashActionBundle, ChugSplashActionType } from './actions'

export const computeBundleId = (
bundleRoot: string,
Expand Down Expand Up @@ -315,3 +316,21 @@ export const getProxyOwner = async (Proxy: Contract) => {
const { args } = (await Proxy.queryFilter('AdminChanged')).at(-1)
return args.newAdmin
}

export const getProxyAt = (signer: Signer, proxyAddress: string): Contract => {
return new Contract(proxyAddress, ProxyABI, signer)
}

export const getCurrentChugSplashActionType = (
bundle: ChugSplashActionBundle,
actionsExecuted: ethers.BigNumber
): ChugSplashActionType => {
return bundle.actions[actionsExecuted.toNumber()].action.actionType
}

export const hasCode = async (
provider: ethers.providers.Provider,
address: string
): Promise<boolean> => {
return '0x' !== (await provider.getCode(address))
}
4 changes: 2 additions & 2 deletions packages/demo/chugsplash/SimpleStorage.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { UserChugSplashConfig } from '@chugsplash/core'
const config: UserChugSplashConfig = {
// Configuration options for the project:
options: {
projectName: 'My First Project',
projectName: 'My First Project2',
},
// Below, we define all of the contracts in the deployment along with their state variables.
contracts: {
Expand All @@ -21,7 +21,7 @@ const config: UserChugSplashConfig = {
SecondSimpleStorage: {
contract: 'SimpleStorage',
variables: {
number: 2,
number: 3,
stored: true,
storageName: 'Second',
otherStorage: '0x1111111111111111111111111111111111111111',
Expand Down
16 changes: 8 additions & 8 deletions packages/demo/contracts/SimpleStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ pragma solidity ^0.8.9;

contract SimpleStorage {
// Define immutable variables
uint8 internal immutable number;
bool internal immutable stored;
address internal immutable otherStorage;
uint8 internal number;
bool internal stored;
address internal otherStorage;
// Leave `storageName` unchanged since Solidity doesn't support immutable strings
string internal storageName;

// We must instantiate the immutable variables in the constructor so that
// Solidity doesn't throw an error.
constructor(uint8 _number, bool _stored, address _otherStorage) {
number = _number;
stored = _stored;
otherStorage = _otherStorage;
}
// constructor(uint8 _number, bool _stored, address _otherStorage) {
// number = _number;
// stored = _stored;
// otherStorage = _otherStorage;
// }

function getNumber() external view returns (uint8) {
return number;
Expand Down
Loading

0 comments on commit d7fff20

Please sign in to comment.