Skip to content
Draft
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
257 changes: 257 additions & 0 deletions specs/interop/contracts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
## Network Upgrade Transactions

Could use some advice on how accurate this deployment plan is. I think it is *not*
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✂️


The interop network upgrade timestamp defines the timestamp at which all functionality in this document is considered
the consensus rules for an OP Stack based network.

Comment on lines +1 to +7
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Notice ⚠️ . Not sure what contract deployments are looking like right now.

The upgrade transaction details below are based on a nightly release at commit
hash `71c460ec7c7c05791ddd841b97bcb664a1f0c753`, and will be updated once a
contracts release is made.

On the [activation block](#activation-block), a set of deposit transaction
based upgrade transactions are deterministically generated by the derivation pipeline in the following order:

<!-- To regenerate the deploy/upgrade tx docs below, run `./scripts/upgrades/gen_interop_upgrade_tx_specs.sh | pbcopy` and then paste here -->
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this up to date?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it likely isn't. This entire file was ripped out of the "derivation.md" section.

Old activation plans had the contracts being deployed on a particular block, but I don't think that's the plan anymore, so I moved it into contract.md and will need to figure out what to do with this whole file.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep an eye on the L2 Contract Manager project which could impact this section e.g. ethereum-optimism/optimism#19165

Copy link
Copy Markdown
Contributor

@maurelian maurelian Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I have noticed that there are not-yet executed NUTs in interop_upgrade_transactions.go, we'll need to make a decision about how to proceed there.


### L2ToL2CrossDomainMessenger Deployment

<!-- Generated with: ./scripts/run_gen_predeploy_docs.sh
--optimism-repo-path ../optimism
--fork-name Interop
--contract-name L2ToL2CrossDomainMessenger
--from-address 0x4220000000000000000000000000000000000001
--from-address-nonce 0
--git-commit-hash 71c460ec7c7c05791ddd841b97bcb664a1f0c753
--eth-rpc-url https://optimism.rpc.subquery.network/public
--proxy-address 0x4200000000000000000000000000000000000023
--copy-contract-bytecode true -->

The `L2ToL2CrossDomainMessenger` contract is deployed.

A deposit transaction is derived with the following attributes:

- `from`: `0x4220000000000000000000000000000000000001`
- `to`: `null`
- `mint`: `0`
- `value`: `0`
- `nonce`: `0`
- `gasLimit`: `1100000`
- `data`: `0x6080604052348015600e575f80fd5b...` ([full bytecode](../static/bytecode/interop-l2-to-l2-cross-domain-messenger-deployment.txt))
- `sourceHash`: `0xf5484697c7a9a791db32a3bf0763bf2ba686c77ae7d4c0a5ee8c222a92a8dcc2`,
computed with the "Upgrade-deposited" type, with `intent = "Interop: L2ToL2CrossDomainMessenger Deployment"`

This results in the Interop L2ToL2CrossDomainMessenger contract being deployed to
`0x0D0eDd0ebd0e94d218670a8De867Eb5C4d37cadD`, to verify:

```bash
cast compute-address --nonce=0 0x4220000000000000000000000000000000000001
Computed Address: 0x0D0eDd0ebd0e94d218670a8De867Eb5C4d37cadD
```

Verify `sourceHash`:

```bash
cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Interop: L2ToL2CrossDomainMessenger Deployment"))
# 0xf5484697c7a9a791db32a3bf0763bf2ba686c77ae7d4c0a5ee8c222a92a8dcc2
```

Verify `data`:

```bash
git checkout 71c460ec7c7c05791ddd841b97bcb664a1f0c753
make build-contracts
jq -r ".bytecode.object" packages/contracts-bedrock/forge-artifacts/L2ToL2CrossDomainMessenger.sol/L2ToL2CrossDomainMessenger.json
```

This transaction MUST deploy a contract with the following code hash
`0x458925c90ec70736600bef3d6529643a0e7a0a848e62626d61314c057b4a71a9`.

To verify the code hash:

```bash
git checkout 71c460ec7c7c05791ddd841b97bcb664a1f0c753
make build-contracts
cast k $(jq -r ".deployedBytecode.object" packages/contracts-bedrock/forge-artifacts/L2ToL2CrossDomainMessenger.sol/L2ToL2CrossDomainMessenger.json)
```

### L2ToL2CrossDomainMessenger Proxy Update

This transaction updates the L2ToL2CrossDomainMessenger Proxy ERC-1967
implementation slot to point to the new L2ToL2CrossDomainMessenger deployment.

A deposit transaction is derived with the following attributes:

- `from`: `0x0000000000000000000000000000000000000000`
- `to`: `0x4200000000000000000000000000000000000023` (L2ToL2CrossDomainMessenger Proxy)
- `mint`: `0`
- `value`: `0`
- `gasLimit`: `50,000`
- `data`: `0x3659cfe60000000000000000000000000d0edd0ebd0e94d218670a8de867eb5c4d37cadd`
- `sourceHash`: `0xe54b4d06bbcc857f41ae00e89d820339ac5ce0034aac722c817b2873e03a7e68`
computed with the "Upgrade-deposited" type, with `intent = "Interop: L2ToL2CrossDomainMessenger Proxy Update"`

Verify data:

```bash
cast concat-hex $(cast sig "upgradeTo(address)") $(cast abi-encode "upgradeTo(address)" 0x0D0eDd0ebd0e94d218670a8De867Eb5C4d37cadD)
# 0x3659cfe60000000000000000000000000d0edd0ebd0e94d218670a8de867eb5c4d37cadd
```

Verify `sourceHash`:

```bash
cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Interop: L2ToL2CrossDomainMessenger Proxy Update"))
# 0xe54b4d06bbcc857f41ae00e89d820339ac5ce0034aac722c817b2873e03a7e68
```

### L2 Gas Limit Requirements

This upgrade requires `3_270_000` in gas, plus `50_000` gas if the CrossL2Inbox proxy is initialized in the same block.
In order to upgrade successfully the following invariant MUST be maintained:

```plaintext
MaxResourceLimit + SystemTxMaxGas + UpgradeGasUsage ≤ L2GasLimit
```

With MaxResourceLimit set to `20_000_000` and SystemTxMaxGas set to `1_000_000`,
this mean every upgrading chain MUST have their L2GasLimit set to greater than
`24_320_000`.

## CrossL2InboxProxy Initialization

On the first block at or after the interop [activation block](#activation-block), where the current chain is in a
dependency set with two or more active chains, a deposit transaction based upgrade transaction is deterministically
generated by the derivation pipeline:

### CrossL2Inbox Deployment

<!-- Generated with: ./scripts/run_gen_predeploy_docs.sh
--optimism-repo-path ../optimism
--fork-name Interop
--contract-name CrossL2Inbox
--from-address 0x4220000000000000000000000000000000000000
--from-address-nonce 0
--git-commit-hash 71c460ec7c7c05791ddd841b97bcb664a1f0c753
--eth-rpc-url https://optimism.rpc.subquery.network/public
--proxy-address 0x4200000000000000000000000000000000000022
--copy-contract-bytecode true -->

The `CrossL2Inbox` contract is deployed.

A deposit transaction is derived with the following attributes:

- `from`: `0x4220000000000000000000000000000000000000`
- `to`: `null`
- `mint`: `0`
- `value`: `0`
- `nonce`: `0`
- `gasLimit`: `420000`
- `data`: `0x6080604052348015600e575f80fd5b...` ([full bytecode](../static/bytecode/interop-cross-l2-inbox-deployment.txt))
- `sourceHash`: `0x6e5e214f73143df8fe6f6054a3ed7eb472d373376458a9c8aecdf23475beb616`,
computed with the "Upgrade-deposited" type, with `intent = "Interop: CrossL2Inbox Deployment"`

This results in the Interop CrossL2Inbox contract being deployed to
`0x691300f512e48B463C2617b34Eef1A9f82EE7dBf`, to verify:

```bash
cast compute-address --nonce=0 0x4220000000000000000000000000000000000000
Computed Address: 0x691300f512e48B463C2617b34Eef1A9f82EE7dBf
```

Verify `sourceHash`:

```bash
cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Interop: CrossL2Inbox Deployment"))
# 0x6e5e214f73143df8fe6f6054a3ed7eb472d373376458a9c8aecdf23475beb616
```

Verify `data`:

```bash
git checkout 71c460ec7c7c05791ddd841b97bcb664a1f0c753
make build-contracts
jq -r ".bytecode.object" packages/contracts-bedrock/forge-artifacts/CrossL2Inbox.sol/CrossL2Inbox.json
```

This transaction MUST deploy a contract with the following code hash
`0x0e7d028dd71bac22d1fb28966043c8d35c3232c78b7fb99fd1db112b5b60d9dd`.

To verify the code hash:

```bash
git checkout 71c460ec7c7c05791ddd841b97bcb664a1f0c753
make build-contracts
cast k $(jq -r ".deployedBytecode.object" packages/contracts-bedrock/forge-artifacts/CrossL2Inbox.sol/CrossL2Inbox.json)
```

### CrossL2Inbox Proxy Update

This transaction updates the CrossL2Inbox Proxy ERC-1967
implementation slot to point to the CrossL2Inbox deployment deployed at the interop activation block.

A deposit transaction is derived with the following attributes:

- `from`: `0x0000000000000000000000000000000000000000`
- `to`: `0x4200000000000000000000000000000000000022` (CrossL2Inbox Proxy)
- `mint`: `0`
- `value`: `0`
- `gasLimit`: `50,000`
- `data`: `0x3659cfe6000000000000000000000000691300f512e48b463c2617b34eef1a9f82ee7dbf`
- `sourceHash`: `0x88c6b48354c367125a59792a93a7b60ad7cd66e516157dbba16558c68a46d3cb`
computed with the "Upgrade-deposited" type, with `intent = "Interop: CrossL2Inbox Proxy Update"`

Verify data:

```bash
cast concat-hex $(cast sig "upgradeTo(address)") $(cast abi-encode "upgradeTo(address)" 0x691300f512e48B463C2617b34Eef1A9f82EE7dBf)
# 0x3659cfe6000000000000000000000000691300f512e48b463c2617b34eef1a9f82ee7dbf
```

Verify `sourceHash`:

```bash
cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Interop: CrossL2Inbox Proxy Update"))
# 0x88c6b48354c367125a59792a93a7b60ad7cd66e516157dbba16558c68a46d3cb
```

### L2 Gas Limit Requirements

Deploying and initializing the CrossL2InboxProxy requires `470_000` in gas. This fits within the standard SystemTxMaxGas
of `1_000_000` even allowing for the gas used by the
[L1 attributes deposited transaction](../glossary.md#l1-attributes-deposited-transaction).

## Expiry Window

The expiry window is the time period after which an initiating message is no longer considered valid.

| Constant | Value |
| --------------- | ---------------------- |
| `EXPIRY_WINDOW` | `604800 secs` (7 days) |
Comment on lines +224 to +230
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this belongs in this section? Ideally we describe where this validity check is enforced.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is in the smart contract layer?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this section used to be in "derivation", where this made a bit more sense.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes this needs to be moved back


## Security Considerations

### Depositing an Executing Message

Deposit transactions (force inclusion transactions) give censorship resistance to layer two networks.
If it were possible to deposit an invalid executing message, this would force the sequencer to reorg. It would
be fairly cheap to continuously deposit invalid executing messages through L1 and cause L2 liveness
instability, therefore deposits are prevented from triggering executing messages.
A future upgrade may enable deposits to trigger executing messages.

### Expiry Window

The expiry window ensures that the proof can execute in a reasonable amount of time. [`EIP-2935`][eip-2935] introduced
the capability to traverse history with sub-linear complexity, however deep lookups remain expensive. App developers and
users, in the event that they encounter a message that has expired but has yet to be relayed, can
[resend the message][resend-msg] in order to complete the process.

### Reliance on History

When fully executing historical blocks, a dependency on historical receipts from remote chains is present.
[EIP-4444][eip-4444] will eventually provide a solution for making historical receipts available without
needing to execute increasingly long chain histories.

[eip-2935]: https://eips.ethereum.org/EIPS/eip-2935
[eip-4444]: https://eips.ethereum.org/EIPS/eip-4444
[resend-msg]: https://github.com/ethereum-optimism/design-docs/blob/25ef5537e39b63cddf1c83479cee9f0e02431dce/protocol/resend-messages.md#L4
14 changes: 3 additions & 11 deletions specs/interop/dependency-set.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ social consensus MUST be used to determine the chain that represents the canonic
particularly impacts the block builder as they SHOULD use the chain id to assist in validation
of executing messages.

The dependency set is configured on a per cluster basis. All chains that are in the dependency set
can accept initiating messages from any other chain in the dependency set, resulting in a mesh.
Chains implicitly belong to their own Dependency Set.

The chain id of the local chain MUST be considered as part of its own dependency set. This allows a chain
to consume logs that it has produced much more cheaply than providing a block hash proof.
Chains define their own dependency sets, but by convention chains are intended to
depend on one another in interop.
Comment on lines +26 to +29
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably revert this unless we're actually going to make the change to support incomplete dependency set graphs. Right now the implementation is very much that all chains in the dependency set can accept initiating messages from any other chain in the dependency set.


## Chain ID

Expand All @@ -47,13 +46,6 @@ It is a known issue that not all software in the Ethereum ecosystem can handle 3
The dependency set is managed in the client software. Adding a chain to the dependency set is
considered an upgrade to the network. It is not possible to remove chains from the dependency set.

## Future Considerations

### Layer 1 as Part of the Dependency Set

The layer one MAY be part of the dependency set in the future. This means that any event
created on layer one is consumable on layer two.

## Security Considerations

### Dependency Set Size
Expand Down
Loading