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.