[WIP] feat: new lockbox#192
Conversation
| @@ -28,9 +28,6 @@ contract SharedLockbox is ISemver { | |||
| /// @notice The address of the SuperchainConfig contract. | |||
| ISuperchainConfig public immutable SUPERCHAIN_CONFIG; | |||
There was a problem hiding this comment.
We should not leak the fact that this is immutable into the abi, could we add a superchainConfig()(address) getter and make internal immutable SUPERCHAIN_CONFIG ?
There was a problem hiding this comment.
This contract address should never change, the SharedLockbox should always have the same SuperchaingConfig contract address, or were you thinking of something else?
There was a problem hiding this comment.
We can make it immutable but no leak the camel case to the abi, then we leak implementation details into the abi
| /// @notice | ||
| contract UpgradeHandler { | ||
| function addDependency(address _supechainConfig, uint256 _chainId, address _systemConfig) external { | ||
| if (msg.sender != Constants.DEPOSITOR_ACCOUNT) revert Unauthorized(); // TODO: check if this is safe enough |
There was a problem hiding this comment.
This is safe enough because only the derivation pipeline can mock this identity
| /// @title UpgradeHandler | ||
| /// @notice | ||
| contract UpgradeHandler { | ||
| function addDependency(address _supechainConfig, uint256 _chainId, address _systemConfig) external { |
|
|
||
| IL2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal( | ||
| _supechainConfig, | ||
| 400_000, // TODO: find an arbitrary value that is enough |
There was a problem hiding this comment.
We need to remove the gas limit on withdrawals, its the source of so much pain
|
|
||
| event ETHMigrated(uint256 amount); | ||
|
|
||
| function migrateLiquidity() external { |
There was a problem hiding this comment.
Do you think its better to move away from the intermediate upgrade contract?
There was a problem hiding this comment.
This approach does simplify multisig operations which is nice
There was a problem hiding this comment.
Yes! Also you can be sure that the ETH liquidity migration is done at the same time as the portal is authorized to withdraw from the lockbox. The other way it has to be manually done and checked before processing the addDependency withdrawal tx .
|
|
||
| // Check the Identifier. | ||
| _checkIdentifier(_id); | ||
| if (!IDependencySet(Predeploys.L1_BLOCK_ATTRIBUTES).isInDependencySet(_id.chainId)) revert InvalidChainId(); |
There was a problem hiding this comment.
If we have this, then we will need the first block to set the dependency set, which makes testing a bit more complicated. The real benefit that I see is on outgoing messages from the L2 to L2 xdm
There was a problem hiding this comment.
We need to make sure that we do not have unprovable logs. Its most simple to assume that you cannot consume logs before the interop start. We would need to move that logic offchain in the block builder, proof and fork choice rule if its not onchain. I think we can get away with keeping everything that was in _checkIdentifier offchain, it will save a bit of gas over time
There was a problem hiding this comment.
Ok perfect, we will remove the check from here but leave it in the L2toL2CDM
| @@ -0,0 +1,30 @@ | |||
| // SPDX-License-Identifier: MIT | |||
| pragma solidity 0.8.25; | |||
There was a problem hiding this comment.
Curious if you have an opinion on the dependency set living in this contract vs the L1Block contract. The tradeoff is with it being in the L1Block contract, it expands the ABI, which causes more gas cost for every single system transaction doing 4byte selector matching. Its likely a minimal amount of gas but it adds up every block. Historically we just always added things to L1Block but this consideration exists
There was a problem hiding this comment.
I like this approach, as we talked, we can have a DependencyManager predeploy handling this
|
These changes generally look good to me |
| // TODO: check if this function makes sense | ||
| /// @notice Initializes the first portal of the cluster. | ||
| /// @param _initialPortal The address of the initial portal. | ||
| function initializePortal(address _initialPortal) external { |
There was a problem hiding this comment.
We agreed that for the first version, we would make the auth be "withdrawal OR multisig" and add a new role to superchain config that represents the multisig. This solves the bootstrapping problem and lets us handle the first upgrade to interop in a simple way. In the future, we can integrate more tightly into OPCM where when deploying a cluster, the first portal is auth'd by op-deployer/opcm. cc @maurelian for visibility
| "type": "bool" | ||
| }, | ||
| { | ||
| "bytes": "20", |
There was a problem hiding this comment.
We may want to move this storage slot away from being managed by solc, its putting it on the same slot as _initialized which is annoying to deal with
There was a problem hiding this comment.
We are going to change everything to use unstructured storage
| string public constant version = "1.1.1-beta.5"; | ||
|
|
||
| /// @notice The Shared Lockbox contract | ||
| ISharedLockbox public sharedLockbox; |
There was a problem hiding this comment.
I would recommend that we either use a spacer to move this away from being in the same slot as initialized or we use a custom setter/getter + a hash to define the slot
There was a problem hiding this comment.
Agree! We are moving to unstructured storage to avoid this problems and future upgrades
|
|
||
| if (_dependencySet.length() == type(uint8).max) revert DependencySetTooLarge(); | ||
| if (_chainId == block.chainid) revert InvalidChainID(); | ||
| if (_chainId == block.chainid) revert InvalidChainID(); // TODO: is this check really necessary? |
There was a problem hiding this comment.
This check is good for preventing footguns altho i don't think its that useful in practice. If we mess up the config for the dep set then we are going to have a bad time regardless of this check. I would be down to remove this to reduce test maintenance
|
|
||
| /// @notice Stores the Identifier in transient storage. | ||
| /// @param _id Identifier to store. | ||
| function _storeIdentifier(Identifier calldata _id) internal { |
There was a problem hiding this comment.
We chatted about this out of band, but we can remove the whole _storeIdentifier function and the getters for the context variables given the only entrypoint now is the validateMessage function
| // Initiate a withdrawal tx to update the dependency set on L1. | ||
| IL2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal( | ||
| _superchainConfig, | ||
| 400_000, // TODO: find an arbitrary value that is enough |
There was a problem hiding this comment.
In the future, I want to make a new "type" of withdrawal message that doesn't have a gas limit for the call and there is a require on the success of the call. This would simplify so much. For now we have to deal with this whole gaslimit thing and be careful of the footgun
| // Set the migrator as an authorized portal so it can lock the ETH while migrating | ||
| vm.prank(address(superchainConfig)); | ||
| sharedLockbox.authorizePortal(address(liquidityMigrator)); | ||
| // sharedLockbox.authorizePortal(address(liquidityMigrator)); |
| import { IL2ToL1MessagePasser } from "interfaces/L2/IL2ToL1MessagePasser.sol"; | ||
| import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; | ||
|
|
||
| /// @custom:proxied true |
There was a problem hiding this comment.
TODO: backport spec ethereum-optimism/specs#495
|
This is good to merge into the feature branch once the comments have been ack'd |
| @@ -1,37 +0,0 @@ | |||
| // SPDX-License-Identifier: MIT | |||
| pragma solidity 0.8.15; | |||
There was a problem hiding this comment.
I think that we still need this contract for the multisig path
There was a problem hiding this comment.
Now the new CLUSTER_MANAGER role can directly call addDependency following the same flow as withdrawals
| /// One-time use logic upgraded over OptimismPortalProxy address and then deprecated by another approval. | ||
| function migrateETH() external { | ||
| uint256 balance = address(this).balance; | ||
| SHARED_LOCKBOX.lockETH{ value: balance }(); |
There was a problem hiding this comment.
This contract could be generic if the abi on the shared lockbox was just fallback rather than a function
| @@ -1,16 +1,23 @@ | |||
| // SPDX-License-Identifier: MIT | |||
| pragma solidity 0.8.15; | |||
| pragma solidity 0.8.25; | |||
| if (_destination == block.chainid) revert MessageDestinationSameChain(); | ||
| if (_target == Predeploys.CROSS_L2_INBOX) revert MessageTargetCrossL2Inbox(); | ||
| if (_target == Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER) revert MessageTargetL2ToL2CrossDomainMessenger(); | ||
| if (!IDependencySet(Predeploys.L1_BLOCK_ATTRIBUTES).isInDependencySet(_destination)) revert InvalidChainId(); |
There was a problem hiding this comment.
I think we need to update the address being called here
There was a problem hiding this comment.
Fixing, also changing L2ToL2CDM tests to be integrated with the setup so this can be catch
There was a problem hiding this comment.
The Setup can't be integrated rn because of how the tests are being handled for transient storage testing. Maybe we can do it once the CommonTest and Setup are migrated to 0.8.25.
* feat: refactor interop feature contracts * fix: add noops comment
* feat: add shared lockbox (#126) * feat: create shared lockbox contract with its interface and unit tests * chore: polish tests and interfaces * chore: run pre-pr * chore: improve natspec * chore: run pre-pr * chore: update compiler version * feat: integrate portal to lockbox (#139) * feat: integrate portal to lockbox * fix: pr fixes * test: refactor assert * feat: add liquidity migrator contract with its unit test and interface (#128) * feat: create shared lockbox contract with its interface and unit tests * chore: polish tests and interfaces * chore: run pre-pr * chore: improve natspec * chore: run pre-pr * feat: add liqudity migrator contract with its unit test and interface * chore: remove underscore on stack var * chore: add todo * chore: run pre-pr * chore: add contract title natspec and proxied * refactor: integrate testing suite with common test * chore: pre-pr * chore: add spec test * feat: integrate system config with superchain config (#140) * feat: integrate portal to lockbox * fix: pr fixes * test: refactor assert * feat: integrate system config with superchain config * fix: remove OPCM interop * test: add dependency counter test * feat: manage dependency set on superchain config (#138) * chore: add zero dependencies check (#142) * fix: pre pr * feat: Add pause check (#145) * feat: Add pause check Co-authored-by: 0xParticle <particle@defi.sucks> Co-authored-by: gotzenx <78360669+gotzenx@users.noreply.github.com> Co-authored-by: Joxess <joxes@defi.sucks> * test: add tests natspecs --------- Co-authored-by: 0xParticle <particle@defi.sucks> Co-authored-by: gotzenx <78360669+gotzenx@users.noreply.github.com> Co-authored-by: Joxess <joxes@defi.sucks> * fix: pre pr and interfaces imports * feat: add upgrader role to superchain config (#163) * feat: use superchain config lockbox in portal (#164) * feat: use superchain config lockbox in portal * test: add new sharedlockbox test * fix: pre pr * feat: liquidity migrator deployment (#166) * feat: liquidity migrator deployment * test: fix comment * test: fix internal variables names * feat: dependency set refactor (#170) * feat: dependency set refactor * fix: deploy script variable name * fix: pr * fix: pr * fix: pre pr * fix: semgrep * fix: merge conflict * [WIP] feat: new lockbox (#192) * chore: partial implementation comments * feat: new lockbox * feat: introduce dependency manager predeploy * feat: remove timestamp check from CrossL2Inbox * feat: introduce cluster manager role and remove immutables * fix: remove unnecessary code, fix tests and setup * feat: use unstructured storage and OZ v5 * fix: L2ToL2CDM dependency set check * fix: dependency manager gas limit * feat: refactor interop feature contracts (#200) * feat: refactor interop feature contracts * fix: add noops comment * feat: adds OptimismPortal migrated flag * test: add missing tests * fix: portal interop storage naming --------- Co-authored-by: Skeletor Spaceman <skeletorspaceman@gmail.com> * fix: pre pr, setup and tests * fix: remove system config interop and add interop portal target check (#205) * fix: remove system config interop and add interop portal check * fix: interop portal target check order * fix: remove wrong comment * fix: refactor portal noops function (#206) * test: add dependency manager and portal interop tests (#209) * feat: initialize shared lockbox in interop portal (#211) * feat: initialize shared lockbox in interop portal * fix: refactor shared lockbox storage getter * fix: lockbox pr fixes (#214) * fix: pre pr * fix: semver lock * fix: semver lock * feat: descope dependency manager (#242) * feat: descope dependency manager * test: fix tests * test: fix tests * chore: improve eth liquidity test (#248) * fix: internal review fixes (#243) * fix: I-0 * fix: I-1 * fix: I-2 * fix: I-3 * fix: I-6 * fix: I-7 * fix: I-9 * fix: pre pr * fix: pre pr * fix: portal withdrawal checks (#255) * fix: portal withdrawal checks * fix: include current withdrawal check * fix: remove unused interop contracts (#256) * test: fix flake tests (#257) * fix: adjust op-deployer interop scripts (#262) * fix: pre pr * fix op-deployer tests * remove dependency code * fix lint * use Bob account --------- Co-authored-by: Disco <131301107+0xDiscotech@users.noreply.github.com> Co-authored-by: AgusDuha <81362284+agusduha@users.noreply.github.com> Co-authored-by: agusduha <agusnduha@gmail.com> Co-authored-by: 0xParticle <particle@defi.sucks> Co-authored-by: gotzenx <78360669+gotzenx@users.noreply.github.com> Co-authored-by: Joxess <joxes@defi.sucks> Co-authored-by: Skeletor Spaceman <skeletorspaceman@gmail.com>
No description provided.