@constellation-labs/contracts-bedrock
v1.1.3
Published
Contracts for Optimism Specs
Downloads
270
Readme
Optimism Smart Contracts (Bedrock)
This package contains the smart contracts that compose the on-chain component of Optimism's upcoming Bedrock upgrade. We've tried to maintain 100% backwards compatibility with the existing system while also introducing new useful features. You can find detailed specifications for the contracts contained within this package here.
A style guide we follow for writing contracts can be found here.
Contracts Overview
Contracts deployed to L1
| Name | Proxy Type | Description |
| ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| L1CrossDomainMessenger
| ResolvedDelegateProxy
| High-level interface for sending messages to and receiving messages from Optimism |
| L1StandardBridge
| L1ChugSplashProxy
| Standardized system for transfering ERC20 tokens to/from Optimism |
| L2OutputOracle
| Proxy
| Stores commitments to the state of Optimism which can be used by contracts on L1 to access L2 state |
| OptimismPortal
| Proxy
| Low-level message passing interface |
| OptimismMintableERC20Factory
| Proxy
| Deploys standard OptimismMintableERC20
tokens that are compatible with either StandardBridge
|
| ProxyAdmin
| - | Contract that can upgrade L1 contracts |
Contracts deployed to L2
| Name | Proxy Type | Description |
| ---------------------------------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------ |
| GasPriceOracle
| Proxy
| Stores L2 gas price configuration values |
| L1Block
| Proxy
| Stores L1 block context information (e.g., latest known L1 block hash) |
| L2CrossDomainMessenger
| Proxy
| High-level interface for sending messages to and receiving messages from L1 |
| L2StandardBridge
| Proxy
| Standardized system for transferring ERC20 tokens to/from L1 |
| L2ToL1MessagePasser
| Proxy
| Low-level message passing interface |
| SequencerFeeVault
| Proxy
| Vault for L2 transaction fees |
| OptimismMintableERC20Factory
| Proxy
| Deploys standard OptimismMintableERC20
tokens that are compatible with either StandardBridge
|
| L2ProxyAdmin
| - | Contract that can upgrade L2 contracts when sent a transaction from L1 |
Legacy and deprecated contracts
| Name | Location | Proxy Type | Description |
| --------------------------------------------------------------- | -------- | ------------------------------------------ | ------------------------------------------------------------------------------------- |
| AddressManager
| L1 | - | Legacy upgrade mechanism (unused in Bedrock) |
| DeployerWhitelist
| L2 | Proxy
| Legacy contract for managing allowed deployers (unused since EVM Equivalence upgrade) |
| L1BlockNumber
| L2 | Proxy
| Legacy contract for accessing latest known L1 block number, replaced by L1Block
|
Installation
We export contract ABIs, contract source code, and contract deployment information for this package via npm
:
npm install @eth-optimism/contracts-bedrock
Development
Dependencies
We work on this repository with a combination of Hardhat and Foundry.
- Install node modules with pnpm (v8) and Node.js (16+):
pnpm install
- Install the correct version of foundry (defined in the .foundryrc file in the root of this repo.
pnpm install:foundry
Build
pnpm build
Tests
pnpm test
Running Echidna tests
You must have Echidna installed.
Contracts targetted for Echidna testing are located in ./contracts/echidna
Each target contract is tested with a separate pnpm command, for example:
pnpm echidna:aliasing
Deployment
The smart contracts are deployed using foundry
with a hardhat-deploy
compatibility layer. When the contracts are deployed,
they will write a temp file to disk that can then be formatted into a hardhat-deploy
style artifact by calling another script.
Configuration
Create or modify a file <network-name>.json
inside of the deploy-config
folder.
By default, the network name will be selected automatically based on the chainid. Alternatively, the DEPLOYMENT_CONTEXT
env var can be used to override the network name.
The spec for the deploy config is defined by the deployConfigSpec
located inside of the hardhat.config.ts
.
Execution
- Set the env vars
ETH_RPC_URL
,PRIVATE_KEY
andETHERSCAN_API_KEY
if contract verification is desired - Deploy the contracts with
forge script -vvv scripts/Deploy.s.sol:Deploy --rpc-url $ETH_RPC_URL --broadcast --private-key $PRIVATE_KEY
Pass the--verify
flag to verify the deployments automatically with Etherscan. - Generate the hardhat deploy artifacts with
forge script -vvv scripts/Deploy.s.sol:Deploy --sig 'sync()' --rpc-url $ETH_RPC_URL --broadcast --private-key $PRIVATE_KEY
Deploying a single contract
All of the functions for deploying a single contract are public
meaning that the --sig
argument to forge script
can be used to
target the deployment of a single contract.
Tools
Layout Locking
We use a system called "layout locking" as a safety mechanism to prevent certain contract variables from being moved to different storage slots accidentally.
To lock a contract variable, add it to the layout-lock.json
file which has the following format:
{
"MyContractName": {
"myVariableName": {
"slot": 1,
"offset": 0,
"length": 32
}
}
}
With the above config, the validate-spacers
hardhat task will check that we have a contract called MyContractName
, that the contract has a variable named myVariableName
, and that the variable is in the correct position as defined in the lock file.
You should add things to the layout-lock.json
file when you want those variables to never change.
Layout locking should be used in combination with diffing the .storage-layout
file in CI.