-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
interop: add Dependency Set Manager & Shared Lockbox design doc #84
base: main
Are you sure you want to change the base?
interop: add Dependency Set Manager & Shared Lockbox design doc #84
Conversation
Co-authored-by: ng <[email protected]>
From a product perspective - the ETH shared lockbox design solves a lot of user pain, by maintaining the invariant that "any amount of ETH can always be withdrawn from L2 to L1 safely", which many protocols have built upon. I think the only concern at this point is the time and resources required to actually ship this securely. Is there some rough scoping of the amount of time this adds to the engineering timeline for interoperable ETH? Who would we need review/support from to feel confident in the security of this upgrade? It's certainly a major change and would want to make sure we get a diverse set of reviews/eyes on this + put together a very thorough Failure Mode Analysis |
Also a stream of work will be making sure that external tooling that relies on the OptimismPortal to calculate ETH stored in a chain is updated as well (e.g. update L2Beat, Defillama, etc.) |
This is a very interesting consideration. Actually, when making ETH interoperable, a shift in the interpretation of liquidity distribution is needed. To show the actual TVL, |
protocol/eth-shared-lockbox.md
Outdated
|
||
# Solution | ||
|
||
We propose an L1 shared liquidity design, achieved by introducing a new `SharedLockbox` in L1 that serves as a singleton ETH contract for the entire interoperable set of chains. New ETH deposits will be forwarded to the lockbox, and the same applies to ETH withdrawals. This could also serve as the singleton contract for gas tokens in the case of CGT chains. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in L1 that serves as a singleton ETH contract
So every interop chains are about to forward ETH into theSharedLockbox
so we should be capable to track the amount of total ETH on the Superchain by checking the balance of this contract?
Or there is still chains that will keep ETH in the previous OptimismPortal
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. In this design, chains that are part of the interoperable graph must adhere to the SharedLockbox
by default, so the total amount of ETH will be there. Although, in principle, one could design this solution as opt-in, it could revert to the main problem and still make them susceptible to liquidity constraints.
I have updated the doc with substantial changes:
|
|
||
### Shared Security Model | ||
|
||
The security model for the set of interoperable chains (commonly called a "cluster") is shared across all involved chains, ensuring that all state transitions are secured. For example, the shared security model allows for defending against any maliciously claimed state transition for any chain within the cluster. This is accomplished through a set of security features at the proof level, such as permissionless proposing, interop-provable proofs (also called shared proofs), and the presence of a single Guardian role across the entire system. This model is independent of the proof system used (e.g., ZK, fault proofs, etc.). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It sounds like this means we will have to move the respected game type out of the portal, where it can be different per-chain, and into the SuperchainConfig, where it's the same for all chains?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I believe that this is required given that there is an idea of shared security between all of the chains
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RespectedGameType is already being moved into AnchorStateRegistry which may begin to resolve this problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first thought, we are going to need to have the RespectedGameType
be the same for all interoperable chains, otherwise we risk heterogeneous (weakest link) security, so it may need to move again, or we will need to use social consensus to make sure all the values are the same and have playbooks for modifying them all atomically. Doable at a small number of chains, but definitely not ideal, so I do think it makes sense to put it in the SuperchainRegistry
given the AnchorStateRegistry
will have its own proxy for each chain
|
||
### Unified Chain Governance | ||
|
||
OP Chains will be governed within a common Chain Cluster governance entity (the Collective). Currently, this entity is responsible for: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this just the standard existing governance process, or is this something new?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is based in a recent draft on op-governed interop set
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We expect this to be the standard existing governance process, as outlined here: https://docs.google.com/document/d/1zeDO241CHl1H8Xl3XqdkmMedP4KQwT4AMRJQ32Hs_HE/edit
protocol/eth-shared-lockbox.md
Outdated
- **Ensuring chains are consistent at the implementation side**, achieved either through trusted deployment methods (e.g., OP Contracts Manager) or by approval after security checks are performed. | ||
- **Approving protocol upgrades** for all chains involved. | ||
- **Adding new chains** to join into the interoperable set, managing the `dependencyManager` role. The final decision is up to governance. | ||
- **Remove existing chains** from the interoperable set. However, such a removal should not be executed without a contingency plan due to the significant implications this could entail. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the implications? Can chains be removed from the interoperable set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chains should not be able to removed, a sequencer could.
"Once a chain is added to the OP-governed interop set it cannot be removed.
A chain servicer (not chain) can be replaced from the OP-governed interop set for failing to satisfy the technical requirements..."
https://docs.google.com/document/d/1zeDO241CHl1H8Xl3XqdkmMedP4KQwT4AMRJQ32Hs_HE/edit
protocol/eth-shared-lockbox.md
Outdated
|
||
### Shared Bridging and SuperchainWETH usage | ||
|
||
In any OP Chain that joins the cluster, the use of `SuperchainWETH` is activated. As a result, the equivalence between ETH deposits and withdrawal history and the actual ETH supply will vary from the outset. In a world with freedom of movement, all real ETH liquidity is theoretically shared across the entire cluster eventually, regardless of how deposits are handled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean that it's "activated", how does this occur at the same time as updating the dependency set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that we assume when a chain receives the interop upgrade (and then joins the dependency set), SuperchainWETH
will also be deployed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why limit SuperchainWETH
to being part of the cluster? It seems exclusive, the contract should always just exist on any chain post interop hardfork being activated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's ok; it should not be a problem
protocol/eth-shared-lockbox.md
Outdated
|
||
# Solution | ||
|
||
The existing problem and considerations motivate us to propose an L1 shared liquidity design through the introduction of a new `SharedLockbox` on L1, which serves as a singleton contract for ETH, given a defined set of interoperable chains. To ensure consistency, the `DependencySetManager` is also introduced to manage the dependency set that the lockbox uses as a source of truth. New ETH deposits will be directed to the lockbox, with the same process applying to ETH withdrawals. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this lockbox only for ETH, and not tokens? Don't tokens have the same withdrawal liquidity problem when moved between chains?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is to keep the scope small for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ETH is the priority for the initial release.
We do expect to come back to deposited tokens but not for the inital release to limit scope.
protocol/eth-shared-lockbox.md
Outdated
|
||
### Managing `DependencySetManager` | ||
|
||
This contract serves as the single point for managing the dependency set of a cluster and is expected to be managed by an admin in the same manner as other L1 OP contracts (proxiable). This contract assumes the role of `dependencyManager` for every `SystemConfigInterop` contract involved. In the case of a simple dependency, the `DependencySetManager` only stores a mapping (or array) of chains added, e.g. given a `chainId`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case of a simple dependency
What does this mean, and what is the other case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, not the best phrasing; we’re assuming a simple dependency only
protocol/eth-shared-lockbox.md
Outdated
Adding a new chain can be done as follows: | ||
|
||
1. `registerChain` is called, which adds the chain to the registry (`chainId` value, `SystemConfig` address, `OptimismPortal2` address) but does not add it to the dependency set. The [Superchain Registry](https://github.com/ethereum-optimism/superchain-registry) or the [OP Contracts Manager](https://specs.optimism.io/experimental/op-contracts-manager.html?highlight=chain#chain-id-source-of-truth) can be used as the source of truth to add chains that have been verified as compatible with this integration. | ||
2. An OP-governed address, who has the role to call `addChain` with the new `chainId`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to store the dependency set twice, in the shared DependencySetManager
/ OPCM source of truth (unsure which it is from the text), and again in the system configs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been already discussed on the Design Review call:
There is no dependency set within SystemConfig; it simply sends the added dependency to L2 to maintain synchronization. Because of this, Matt was ok with the approach presented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be in favor of adding the dependency set to the L1 system config to be honest, no need to do so but its about keeping a symmetrical API per chain, since the data is available on L2
protocol/eth-shared-lockbox.md
Outdated
|
||
// Function to add a chain to the dependency set | ||
function addChain(uint256 chainId) external onlyOwner { | ||
require(systemConfigInterops[chainId] != address(0), "DependencySetManager: Chain not registered"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
protocol/eth-shared-lockbox.md
Outdated
- `lockETH`: Accepts ETH from the `depositTransaction` originating from a valid `OptimismPortal2`. | ||
- `unlockETH`: Releases ETH from the `finalizeWithdrawalTransaction` originating from a valid `OptimismPortal2`. | ||
|
||
Access control for `lockETH` and `unlockETH` is validated against the list reated by `registerChain`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo, "reated"
protocol/eth-shared-lockbox.md
Outdated
|
||
### `OptimismPortal2` upgrade process | ||
|
||
A one-time L1 liquidity migration is required for each approved chain. By using an intermediate contract during the upgrade, all ETH held by the `OptimismPortal` can be transferred to the `SharedLockbox` within the `initialize` function. After this migration, the `OptimismPortal` is upgraded to the new version with the desired functionality. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What alternative migration flows have we considered and what are the tradeoffs? For example, we could just add a forwardETH()
method to the portals that forwards all ETH balance to the lockbox whenever it's called, and call it from the initialize
function. (We wouldn't want this forwardETH
method callable for chains not in the interop set so it'd have to check for that and revert accordingly)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are exploring various migration options, with the goal of minimizing the amount of permanently added code. We’ll share some insights on this soon.
protocol/eth-shared-lockbox.md
Outdated
- Introduce the `DependencySetManager` contract: This contract manages and tracks the dependency graph. | ||
- Introduce the `SharedLockbox` contract: It acts as an escrow for ETH, receiving deposits and allows withdrawals from approved `OptimismPortal2` contracts. The `DependencySetManager` contract serves as the source of truth of the lockbox. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What alternatives are there to adding these two contracts? For example, can the functionality of the DependencySetManager
instead live in SuperchainConfig
or OPCM?
My main concern is that we have a lot of L1 contracts already so our architecture + auth can be confusing. I'd like to work towards reducing the number of contracts (when it makes sense to, i.e. good separation of concerns is still important). But both SuperchainConfig
and OPCM feel like suitable candidates for the role of DependencySetManager
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A way to think about this is that there is a difference from the ways that the protocol may work, and the way that we want to the protocol to work. Right now we want to enforce a bidirectional relationship for all dependencies. Whatever contract is the dependencyManager
role should enforce this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not opinionated on what contract does this enforcement, whether its the SuperchainConfig
or not, we should inspect where the roles live and come to a shared optimization target
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are considering consolidating all new functionality into the SuperchainConfig
, though having a specific contract doesn't sound like a bad option either.
This contract would manage the dependency set and the ability to add a chain to it.
Also we should consider that this contract will have to be set as the dependency manager of the SystemConfig
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be in favor of either the SuperchainConfig
or adding another contract, with slight preference for the SuperchainConfig
to reduce the number of contracts that we need to manage/deploy
|
||
The following components require an audit of the new and modified contracts: `OptimismPortal2`, `SharedLockbox`, `SystemConfigInterop`, `L1BlockInterop`, and `DependencySetManager`. This also includes the scripts necessary to perform the migration. | ||
|
||
# Alternatives Considered |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related to some of my questions about (why do we need dependency set info in the system config and the DependencySetManager, and do we really need the DependencySetManager), I'd like to see more alternatives and justification for this specific lockbox design, compared to other lockbox designs.
An example: Have we considered deprecating the portal, and having the lockbox emit deposit events with a chain ID? The obvious downside is now this requires changes to the derivation path, but it does mean we can get rid of an entire contract which is nice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deprecating the portal in favor of developing a new SharedPortal sounds like a good long-term goal, but it would be far beyond the scope of the ETH Lockbox feature. Creating this new SharedPortal looks like a massive and highly sensitive project that would need debate and coordination across multiple teams to bring it to life. We think this is a valid but complex question that could significantly alter the direction of this task. We're interested to hear what others think about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to not add more derivation changes. We have considered a "beacon" style deposit contract, this could be on the roadmap in the future but this feature doesn't make or break the design. I am in favor of the minimal diff that maintains the portal contracts and simply holds its ether in a shared lockbox
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do need a dependency set manager that orchestrates the dependency set of the entire cluster, unless we do have a shared system config
|
||
The implementation would require iterating through the dependency set, determined on L1 to find the next `OptimismPortal` with available funds. This approach incurs more modifications to the `OptimismPortal`, increasing complexity. | ||
|
||
# Risks & Uncertainties |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to see security considerations fleshed out a bit more. Arguably the risks aren't that much different than storing all this ETH in separate portal proxies that point to the same implementation, but there are risks with both the ETH migration and having a giant honeypot of funds. What is the simplest and most secure migration approach and architecture we can come up with? How do we gain confidence in the implementations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're gonna focus on this part; we will come back with some different approaches that we're currently analyzing
protocol/eth-shared-lockbox.md
Outdated
|
||
// Function to add a chain to the dependency set | ||
function addChain(uint256 chainId) external onlyOwner { | ||
require(systemConfigInterops[chainId] != address(0), "DependencySetManager: Chain not registered"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will rename SystemConfigInterop
to SystemConfig
, its a temporary naming scheme. Same with renaming OptimismPortal2
to OptimismPortal
, so you can refer to them with those names
protocol/eth-shared-lockbox.md
Outdated
|
||
A minimal set of functions should include: | ||
|
||
- `lockETH`: Accepts ETH from the `depositTransaction` originating from a valid `OptimismPortal2`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something to think about is decoupling the proof verification logic itself from the OptimismPortal
completely, see the discussion in ethereum-optimism/specs#361
This will help to reduce the size of the OptimismPortal
contract, it is at max codesize. It also would make it easier to slot in alternative proof systems. Just bringing this up because its related code, this may not be a good idea to include as part of this change as its scope bloat.
Its likely possible that the required modifications to the portal for this feature can be included without going over the codesize, but if its absolutely not possible to stay below max codesize then we will need to do the above issue first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once we define the migration approach, we will try to apply the code changes needed and check if it reach the size limit. If we are able to avoid hitting the limit, we will leave it like that and apply the changes to the portal. If we hit the size limit, we will need to revisit and tackle the possible portal decoupling.
|
One consideration now that we have a contract for managing the dependency set - should we make the full dependency set legible from within each L2? This would prevent the need to send to chains that do not have the local chain in their dependency set We could assume this by observing the dependency set locally when sending a message through the |
We need to align on whether or not we want to be supporting non-complete graphs in the dependency set. We can make assumptions that it must be a full mesh. Right now we do not make this assumption |
Lets not worry about this as it adds scope and we can revisit in the future |
Co-authored-by: ng [email protected], agusduha [email protected]
Description
The following design doc cover a previous discussed issue on ETH withdrawals introduced by interop. The Shared lockbox is presented as the most convenient solution to solve this problem. However, it is known that the design also is the interest for various aspects of the Superchain design, such as chain management, core interop, and others, which need to be carefully discussed.
Additional context
This doesn't address the case for L1 bridged tokens.