github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/README.md (about) 1 # OP Stack Smart Contracts 2 3 This package contains the L1 and L2 smart contracts for the OP Stack. 4 Detailed specifications for the contracts contained within this package can be found at [specs.optimism.io](https://specs.optimism.io). 5 High-level information about these contracts can be found within this README and within the [Optimism Developer Docs](https://docs.optimism.io). 6 7 <!-- START doctoc generated TOC please keep comment here to allow auto update --> 8 <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> 9 ## Table of Contents 10 11 - [Architecture Overview](#architecture-overview) 12 - [Core L1 Smart Contracts](#core-l1-smart-contracts) 13 - [Notes for Core L1 Smart Contracts](#notes-for-core-l1-smart-contracts) 14 - [Core L2 Smart Contracts](#core-l2-smart-contracts) 15 - [Notes for Core L2 Smart Contracts](#notes-for-core-l2-smart-contracts) 16 - [Smart Contract Proxies](#smart-contract-proxies) 17 - [External Usage](#external-usage) 18 - [Using OP Stack Contracts in Solidity](#using-op-stack-contracts-in-solidity) 19 - [Using OP Stack Contracts in JavaScript](#using-op-stack-contracts-in-javascript) 20 - [Deployed Addresses](#deployed-addresses) 21 - [Contributing](#contributing) 22 - [Contributing Guide](#contributing-guide) 23 - [Style Guide](#style-guide) 24 - [Deployment](#deployment) 25 - [Configuration](#configuration) 26 - [Execution](#execution) 27 - [Deploying a single contract](#deploying-a-single-contract) 28 - [Testing](#testing) 29 - [Test Setup](#test-setup) 30 - [Static Analysis](#static-analysis) 31 32 <!-- END doctoc generated TOC please keep comment here to allow auto update --> 33 34 ## Architecture Overview 35 36 > **NOTE**: Smart contract names in the architecture diagrams below are links to source code. Click them! 37 38 ### Core L1 Smart Contracts 39 40 Below you'll find an architecture diagram describing the core L1 smart contracts for the OP Stack. 41 Smart contracts that are considered "peripheral" and not core to the operation of the OP Stack system are described separately. 42 43 ```mermaid 44 graph LR 45 subgraph "External Contracts" 46 ExternalERC20(External ERC20 Contracts) 47 ExternalERC721(External ERC721 Contracts) 48 end 49 50 subgraph "L1 Smart Contracts" 51 BatchDataEOA(<a href="https://etherscan.io/address/0xff00000000000000000000000000000000000010">Batch Inbox Address</a>) 52 L1StandardBridge(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L1/L1StandardBridge.sol">L1StandardBridge</a>) 53 L1ERC721Bridge(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol">L1ERC721Bridge</a>) 54 L1CrossDomainMessenger(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol">L1CrossDomainMessenger</a>) 55 L2OutputOracle(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L1/L2OutputOracle.sol">L2OutputOracle</a>) 56 OptimismPortal(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L1/OptimismPortal.sol">OptimismPortal</a>) 57 SuperchainConfig(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L1/SuperchainConfig.sol">SuperchainConfig</a>) 58 SystemConfig(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L1/SystemConfig.sol">SystemConfig</a>) 59 end 60 61 subgraph "User Interactions" 62 Users(Users) 63 end 64 65 subgraph "System Interactions" 66 Batcher(Batcher) 67 Proposer(Proposer) 68 Guardian(Guardian) 69 end 70 71 subgraph "Layer 2 Interactions" 72 L2Nodes(Layer 2 Nodes) 73 end 74 75 Batcher -->|publish transaction batches| BatchDataEOA 76 Proposer -->|propose state outputs| L2OutputOracle 77 Guardian -->|remove invalid state outputs| L2OutputOracle 78 79 ExternalERC20 <-->|mint/burn/transfer| L1StandardBridge 80 ExternalERC721 <-->|mint/burn/transfer| L1ERC721Bridge 81 82 L1StandardBridge <-->|send/receive message| L1CrossDomainMessenger 83 L1ERC721Bridge <-->|send/receive message| L1CrossDomainMessenger 84 L1CrossDomainMessenger <-->|package/send/receive message| OptimismPortal 85 L1StandardBridge -.->|query pause state| SuperchainConfig 86 L1ERC721Bridge -.->|query pause state| SuperchainConfig 87 L1CrossDomainMessenger -.->|query pause state| SuperchainConfig 88 OptimismPortal -.->|query pause state| SuperchainConfig 89 90 OptimismPortal -.->|query config| SystemConfig 91 OptimismPortal -.->|query proposed states| L2OutputOracle 92 93 Users <-->|deposit/withdraw ETH/ERC20| L1StandardBridge 94 Users <-->|deposit/withdraw ERC721| L1ERC721Bridge 95 Users -->|prove/execute withdrawal transactions| OptimismPortal 96 97 L2Nodes -.->|fetch transaction batches| BatchDataEOA 98 L2Nodes -.->|verify output roots| L2OutputOracle 99 L2Nodes -.->|fetch deposit events| OptimismPortal 100 101 classDef extContracts stroke:#ff9,stroke-width:2px; 102 classDef l1Contracts stroke:#bbf,stroke-width:2px; 103 classDef l1EOA stroke:#bbb,stroke-width:2px; 104 classDef userInt stroke:#f9a,stroke-width:2px; 105 classDef systemUser stroke:#f9a,stroke-width:2px; 106 classDef l2Nodes stroke:#333,stroke-width:2px 107 class ExternalERC20,ExternalERC721 extContracts; 108 class L1StandardBridge,L1ERC721Bridge,L1CrossDomainMessenger,L2OutputOracle,OptimismPortal,SuperchainConfig,SystemConfig l1Contracts; 109 class BatchDataEOA l1EOA; 110 class Users userInt; 111 class Batcher,Proposer,Guardian systemUser; 112 class L2Nodes l2Nodes; 113 ``` 114 115 #### Notes for Core L1 Smart Contracts 116 117 - The `Batch Data Address` described above (**highlighted in GREY**) is *not* a smart contract and is instead simply an arbitrarily chosen account that is assumed to have no known private key. This account is typically chosen as the account `0xFF0000....<L2 chain ID>` where `<L2 chain ID>` is chain ID of the Layer 2 network for which the data is being posted. For instance, for OP Mainnet, this account is chosen as `0xFF00000000000000000000000000000000000010`. However, this is not a strict requirement and some OP Stack chains may not follow this convention. 118 - Smart contracts that sit behind `Proxy` contracts are **highlighted in BLUE**. Refer to the [Smart Contract Proxies](#smart-contract-proxies) section below to understand how these proxies are designed. 119 - The `L1CrossDomainMessenger` contract sits behind the [`ResolvedDelegateProxy`](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol) contract, a legacy proxy contract type used within older versions of the OP Stack. This proxy type is used exclusively for the `L1CrossDomainMessenger` to maintain backwards compatibility. 120 - The `L1StandardBridge` contract sits behind the [`L1ChugSplashProxy`](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol) contract, a legacy proxy contract type used within older versions of the OP Stack. This proxy type is used exclusively for the `L1StandardBridge` contract to maintain backwards compatibility. 121 122 ### Core L2 Smart Contracts 123 124 Here you'll find an architecture diagram describing the core OP Stack smart contracts that exist natively on the L2 chain itself. 125 126 ```mermaid 127 graph LR 128 subgraph "Layer 1 (Ethereum)" 129 L1SmartContracts(L1 Smart Contracts) 130 end 131 132 subgraph "L2 Client" 133 L2Node(L2 Node) 134 end 135 136 subgraph "L2 System Contracts" 137 L1Block(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L2/L1Block.sol">L1Block</a>) 138 GasPriceOracle(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L2/GasPriceOracle.sol">GasPriceOracle</a>) 139 L1FeeVault(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L2/L1FeeVault.sol">L1FeeVault</a>) 140 BaseFeeVault(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L2/BaseFeeVault.sol">BaseFeeVault</a>) 141 SequencerFeeVault(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L2/SequencerFeeVault.sol">SequencerFeeVault</a>) 142 end 143 144 subgraph "L2 Bridge Contracts" 145 L2CrossDomainMessenger(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol">L2CrossDomainMessenger</a>) 146 L2ToL1MessagePasser(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol">L2ToL1MessagePasser</a>) 147 L2StandardBridge(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L2/L2StandardBridge.sol">L2StandardBridge</a>) 148 L2ERC721Bridge(<a href="https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol">L2ERC721Bridge</a>) 149 end 150 151 subgraph "Transactions" 152 DepositTransaction(Deposit Transaction) 153 UserTransaction(User Transaction) 154 end 155 156 subgraph "External Contracts" 157 ExternalERC20(External ERC20 Contracts) 158 ExternalERC721(External ERC721 Contracts) 159 end 160 161 subgraph "Remaining L2 Universe" 162 OtherContracts(Any Contracts and Addresses) 163 end 164 165 L2Node -.->|derives chain from| L1SmartContracts 166 L2Node -->|updates| L1Block 167 L2Node -->|distributes fees to| L1FeeVault 168 L2Node -->|distributes fees to| BaseFeeVault 169 L2Node -->|distributes fees to| SequencerFeeVault 170 L2Node -->|derives from deposits| DepositTransaction 171 L2Node -->|derives from chain data| UserTransaction 172 173 UserTransaction -->|can trigger| OtherContracts 174 DepositTransaction -->|maybe triggers| L2CrossDomainMessenger 175 DepositTransaction -->|can trigger| OtherContracts 176 177 ExternalERC20 <-->|mint/burn/transfer| L2StandardBridge 178 ExternalERC721 <-->|mint/burn/transfer| L2ERC721Bridge 179 180 L2StandardBridge <-->|sends/receives messages| L2CrossDomainMessenger 181 L2ERC721Bridge <-->|sends/receives messages| L2CrossDomainMessenger 182 GasPriceOracle -.->|queries| L1Block 183 L2CrossDomainMessenger -->|sends messages| L2ToL1MessagePasser 184 185 classDef extContracts stroke:#ff9,stroke-width:2px; 186 classDef l2Contracts stroke:#bbf,stroke-width:2px; 187 classDef transactions stroke:#fba,stroke-width:2px; 188 classDef l2Node stroke:#f9a,stroke-width:2px; 189 190 class ExternalERC20,ExternalERC721 extContracts; 191 class L2CrossDomainMessenger,L2ToL1MessagePasser,L2StandardBridge,L2ERC721Bridge l2Contracts; 192 class L1Block,L1FeeVault,BaseFeeVault,SequencerFeeVault,GasPriceOracle l2Contracts; 193 class UserTransaction,DepositTransaction transactions; 194 class L2Node l2Node; 195 ``` 196 197 #### Notes for Core L2 Smart Contracts 198 199 - Contracts highlighted as "L2 System Contracts" are updated or mutated automatically as part of the chain derivation process. Users typically do not mutate these contracts directly, except in the case of the `FeeVault` contracts where any user may trigger a withdrawal of collected fees to the pre-determined withdrawal address. 200 - Smart contracts that sit behind `Proxy` contracts are **highlighted in BLUE**. Refer to the [Smart Contract Proxies](#smart-contract-proxies) section below to understand how these proxies are designed. 201 - User interactions for the "L2 Bridge Contracts" have been omitted from this diagram but largely follow the same user interactions described in the architecture diagram for the [Core L1 Smart Contracts](#core-l1-smart-contracts). 202 203 ### Smart Contract Proxies 204 205 Most L1 and L2 smart contracts for OP Stack chains today sit behind `Proxy` contracts that themselves are managed by a `ProxyAdmin` contract. 206 The `ProxyAdmin` contract is controlled by some `owner` address that can be any EOA or smart contract. 207 Below you'll find a diagram that explains the behavior of the typical proxy contract. 208 209 ```mermaid 210 graph LR 211 ProxyAdminOwner(Proxy Admin Owner) 212 ProxyAdmin(<a href="https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/ProxyAdmin.sol">ProxyAdmin</a>) 213 214 subgraph "Logical Smart Contract" 215 Proxy(<a href="https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/Proxy.sol">Proxy</a>) 216 Implementation(Implementation) 217 end 218 219 ProxyAdminOwner -->|manages| ProxyAdmin 220 ProxyAdmin -->|upgrades| Proxy 221 Proxy -->|delegatecall| Implementation 222 223 classDef l1Contracts stroke:#bbf,stroke-width:2px; 224 classDef systemUser stroke:#f9a,stroke-width:2px; 225 class Proxy l1Contracts; 226 class ProxyAdminOwner systemUser; 227 ``` 228 229 ## External Usage 230 231 ### Using OP Stack Contracts in Solidity 232 233 OP Stack smart contracts are published to NPM and can be installed via: 234 235 ```sh 236 npm install @eth-optimism/contracts-bedrock. 237 ``` 238 239 Refer to the [Optimism Developer Docs](https://docs.optimism.io/builders/dapp-developers/contracts/system-contracts#using-system-contracts-in-solidity) for additional information about how to use this package. 240 241 ### Using OP Stack Contracts in JavaScript 242 243 Contract ABIs and addresses are published to NPM in a separate package and can be installed via: 244 245 ```sh 246 npm install @eth-optimism/contracts-ts 247 ``` 248 249 Refer to the [Optimism Developer Docs](https://docs.optimism.io/builders/dapp-developers/contracts/system-contracts#using-system-contracts-in-javascript) for additional information about how to use this package. 250 251 ### Deployed Addresses 252 253 See the [Optimism Developer Docs](https://docs.optimism.io/chain/addresses) for the deployed addresses of these smart contracts for OP Mainnet and OP Sepolia. 254 255 ## Contributing 256 257 ### Contributing Guide 258 259 Contributions to the OP Stack are always welcome. 260 Please refer to the [CONTRIBUTING.md](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/CONTRIBUTING.md) for more information about how to contribute to the OP Stack smart contracts. 261 262 ### Style Guide 263 264 OP Stack smart contracts should be written according to the [STYLE_GUIDE.md](./STYLE_GUIDE.md) found within this repository. 265 Maintaining a consistent code style makes code easier to review and maintain, ultimately making the development process safer. 266 267 ## Deployment 268 269 The smart contracts are deployed using `foundry` with a `hardhat-deploy` compatibility layer. When the contracts are deployed, 270 they will write a temp file to disk that can then be formatted into a `hardhat-deploy` style artifact by calling another script. 271 272 The addresses in the `deployments` directory will be read into the script based on the backend's chain id. 273 To manually define the set of addresses used in the script, set the `CONTRACT_ADDRESSES_PATH` env var to a path on the local 274 filesystem that points to a JSON file full of key value pairs where the keys are names of contracts and the 275 values are addresses. This works well with the JSON files in `superchain-ops`. 276 277 ### Configuration 278 279 Create or modify a file `<network-name>.json` inside of the [`deploy-config`](./deploy-config/) folder. 280 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. 281 The spec for the deploy config is defined by the `deployConfigSpec` located inside of the [`hardhat.config.ts`](./hardhat.config.ts). 282 283 ### Execution 284 285 Before deploying the contracts, you can verify the state diff produced by the deploy script using the `runWithStateDiff()` function signature which produces the outputs inside [`snapshots/state-diff/`](./snapshots/state-diff). 286 Run the deployment with state diffs by executing: `forge script -vvv scripts/Deploy.s.sol:Deploy --sig 'runWithStateDiff()' --rpc-url $ETH_RPC_URL --broadcast --private-key $PRIVATE_KEY`. 287 288 1. Set the env vars `ETH_RPC_URL`, `PRIVATE_KEY` and `ETHERSCAN_API_KEY` if contract verification is desired 289 1. Deploy the contracts with `forge script -vvv scripts/Deploy.s.sol:Deploy --rpc-url $ETH_RPC_URL --broadcast --private-key $PRIVATE_KEY` 290 Pass the `--verify` flag to verify the deployments automatically with Etherscan. 291 1. 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` 292 293 ### Deploying a single contract 294 295 All of the functions for deploying a single contract are `public` meaning that the `--sig` argument to `forge script` can be used to 296 target the deployment of a single contract. 297 298 ## Testing 299 300 ### Test Setup 301 302 The Solidity unit tests use the same codepaths to set up state that are used in production. The same L1 deploy script is used to deploy the L1 contracts for the in memory tests 303 and the L2 state is set up using the same L2 genesis generation code that is used for production and then loaded into foundry via the `vm.loadAllocs` cheatcode. This helps 304 to reduce the overhead of maintaining multiple ways to set up the state as well as give additional coverage to the "actual" way that the contracts are deployed. 305 306 The L1 contract addresses are held in `deployments/hardhat/.deploy` and the L2 test state is held in a `.testdata` directory. The L1 addresses are used to create the L2 state 307 and it is possible for stale addresses to be pulled into the L2 state, causing tests to fail. Stale addresses may happen if the order of the L1 deployments happen differently 308 since some contracts are deployed using `CREATE`. Run `pnpm clean` and rerun the tests if they are failing for an unknown reason. 309 310 ### Static Analysis 311 312 `contracts-bedrock` uses [slither](https://github.com/crytic/slither) as its primary static analysis tool. 313 Slither will be run against PRs as part of CI, and new findings will be reported as a comment on the PR. 314 CI will fail if there are any new findings of medium or higher severity, as configured in the repo's Settings > Code Security and Analysis > Code Scanning > Protection rules setting. 315 316 There are two corresponding jobs in CI: one calls "Slither Analysis" and one called "Code scanning results / Slither". 317 The former will always pass if Slither runs successfully, and the latter will fail if there are any new findings of medium or higher severity. 318 319 Existing findings can be found in the repo's Security tab > [Code Scanning](https://github.com/ethereum-optimism/optimism/security/code-scanning) section. 320 You can view findings for a specific PR using the `pr:{number}` filter, such [`pr:9405`](https://github.com/ethereum-optimism/optimism/security/code-scanning?query=is:open+pr:9405). 321 322 For each finding, either fix it locally and push a new commit, or dismiss it through the PR comment's UI. 323 324 Note that you can run slither locally by running `slither .`, but because it does not contain the triaged results from GitHub, it will be noisy. 325 Instead, you should run `slither ./path/to/contract.sol` to run it against a specific file.