diff --git a/src/bridge/AbsOutbox.sol b/src/bridge/AbsOutbox.sol index 2b87c726..2678f1fb 100644 --- a/src/bridge/AbsOutbox.sol +++ b/src/bridge/AbsOutbox.sol @@ -12,7 +12,8 @@ import { UnknownRoot, AlreadySpent, BridgeCallFailed, - HadZeroInit + HadZeroInit, + BadPostUpgradeInit } from "../libraries/Error.sol"; import "./IBridge.sol"; import "./IOutbox.sol"; @@ -76,6 +77,19 @@ abstract contract AbsOutbox is DelegateCallAware, IOutbox { rollup = address(_bridge.rollup()); } + function postUpgradeInit() external onlyDelegated onlyProxyOwner { + // prevent postUpgradeInit within a withdrawal + if (context.l2Block != L2BLOCK_DEFAULT_CONTEXT) revert BadPostUpgradeInit(); + context = L2ToL1Context({ + l2Block: L2BLOCK_DEFAULT_CONTEXT, + l1Block: L1BLOCK_DEFAULT_CONTEXT, + timestamp: TIMESTAMP_DEFAULT_CONTEXT, + outputId: OUTPUTID_DEFAULT_CONTEXT, + sender: SENDER_DEFAULT_CONTEXT, + withdrawalAmount: _defaultContextAmount() + }); + } + function updateSendRoot(bytes32 root, bytes32 l2BlockHash) external { if (msg.sender != rollup) revert NotRollup(msg.sender, rollup); roots[root] = l2BlockHash; diff --git a/src/bridge/IOutbox.sol b/src/bridge/IOutbox.sol index 06358170..be888634 100644 --- a/src/bridge/IOutbox.sol +++ b/src/bridge/IOutbox.sol @@ -119,4 +119,10 @@ interface IOutbox { uint256 path, bytes32 item ) external pure returns (bytes32); + + /** + * @dev function to be called one time during the outbox upgrade process + * this is used to fix the storage slots + */ + function postUpgradeInit() external; } diff --git a/src/libraries/Error.sol b/src/libraries/Error.sol index beb0afc8..e4776d80 100644 --- a/src/libraries/Error.sol +++ b/src/libraries/Error.sol @@ -7,9 +7,12 @@ pragma solidity ^0.8.4; /// @dev Init was already called error AlreadyInit(); -/// Init was called with param set to zero that must be nonzero +/// @dev Init was called with param set to zero that must be nonzero error HadZeroInit(); +/// @dev Thrown when post upgrade init validation fails +error BadPostUpgradeInit(); + /// @dev Thrown when non owner tries to access an only-owner function /// @param sender The msg.sender who is not the owner /// @param owner The owner address diff --git a/src/test-helpers/OutboxWithoutOptTester.sol b/src/test-helpers/OutboxWithoutOptTester.sol index 50f378ac..0036e3c1 100644 --- a/src/test-helpers/OutboxWithoutOptTester.sol +++ b/src/test-helpers/OutboxWithoutOptTester.sol @@ -48,6 +48,8 @@ contract OutboxWithoutOptTester is DelegateCallAware, IOutbox { rollup = address(_bridge.rollup()); } + function postUpgradeInit() external {} + function updateSendRoot(bytes32 root, bytes32 l2BlockHash) external override { //if (msg.sender != rollup) revert NotRollup(msg.sender, rollup); //test only!!! roots[root] = l2BlockHash;