Commit bdcaf29a authored by Mark Tyneway's avatar Mark Tyneway

contracts-bedrock: l2 output oracle storage

parent b604d42e
This diff is collapsed.
...@@ -311,20 +311,21 @@ contract Deploy is Deployer { ...@@ -311,20 +311,21 @@ contract Deploy is Deployer {
L2OutputOracle oracle = new L2OutputOracle({ L2OutputOracle oracle = new L2OutputOracle({
_submissionInterval: cfg.l2OutputOracleSubmissionInterval(), _submissionInterval: cfg.l2OutputOracleSubmissionInterval(),
_l2BlockTime: cfg.l2BlockTime(), _l2BlockTime: cfg.l2BlockTime(),
_startingBlockNumber: cfg.l2OutputOracleStartingBlockNumber(),
_startingTimestamp: cfg.l2OutputOracleStartingTimestamp(),
_proposer: cfg.l2OutputOracleProposer(),
_challenger: cfg.l2OutputOracleChallenger(),
_finalizationPeriodSeconds: cfg.finalizationPeriodSeconds() _finalizationPeriodSeconds: cfg.finalizationPeriodSeconds()
}); });
require(oracle.SUBMISSION_INTERVAL() == cfg.l2OutputOracleSubmissionInterval()); require(oracle.SUBMISSION_INTERVAL() == cfg.l2OutputOracleSubmissionInterval());
require(oracle.submissionInterval() == cfg.l2OutputOracleSubmissionInterval());
require(oracle.L2_BLOCK_TIME() == cfg.l2BlockTime()); require(oracle.L2_BLOCK_TIME() == cfg.l2BlockTime());
require(oracle.PROPOSER() == cfg.l2OutputOracleProposer()); require(oracle.l2BlockTime() == cfg.l2BlockTime());
require(oracle.CHALLENGER() == cfg.l2OutputOracleChallenger()); require(oracle.PROPOSER() == address(0));
require(oracle.proposer() == address(0));
require(oracle.CHALLENGER() == address(0));
require(oracle.challenger() == address(0));
require(oracle.FINALIZATION_PERIOD_SECONDS() == cfg.finalizationPeriodSeconds()); require(oracle.FINALIZATION_PERIOD_SECONDS() == cfg.finalizationPeriodSeconds());
require(oracle.startingBlockNumber() == cfg.l2OutputOracleStartingBlockNumber()); require(oracle.finalizationPeriodSeconds() == cfg.finalizationPeriodSeconds());
require(oracle.startingTimestamp() == cfg.l2OutputOracleStartingTimestamp()); require(oracle.startingBlockNumber() == 0);
require(oracle.startingTimestamp() == 0);
save("L2OutputOracle", address(oracle)); save("L2OutputOracle", address(oracle));
console.log("L2OutputOracle deployed at %s", address(oracle)); console.log("L2OutputOracle deployed at %s", address(oracle));
...@@ -651,7 +652,9 @@ contract Deploy is Deployer { ...@@ -651,7 +652,9 @@ contract Deploy is Deployer {
L2OutputOracle.initialize, L2OutputOracle.initialize,
( (
cfg.l2OutputOracleStartingBlockNumber(), cfg.l2OutputOracleStartingBlockNumber(),
cfg.l2OutputOracleStartingTimestamp() cfg.l2OutputOracleStartingTimestamp(),
cfg.l2OutputOracleProposer(),
cfg.l2OutputOracleChallenger()
) )
) )
}); });
...@@ -661,10 +664,15 @@ contract Deploy is Deployer { ...@@ -661,10 +664,15 @@ contract Deploy is Deployer {
console.log("L2OutputOracle version: %s", version); console.log("L2OutputOracle version: %s", version);
require(oracle.SUBMISSION_INTERVAL() == cfg.l2OutputOracleSubmissionInterval()); require(oracle.SUBMISSION_INTERVAL() == cfg.l2OutputOracleSubmissionInterval());
require(oracle.submissionInterval() == cfg.l2OutputOracleSubmissionInterval());
require(oracle.L2_BLOCK_TIME() == cfg.l2BlockTime()); require(oracle.L2_BLOCK_TIME() == cfg.l2BlockTime());
require(oracle.l2BlockTime() == cfg.l2BlockTime());
require(oracle.PROPOSER() == cfg.l2OutputOracleProposer()); require(oracle.PROPOSER() == cfg.l2OutputOracleProposer());
require(oracle.proposer() == cfg.l2OutputOracleProposer());
require(oracle.CHALLENGER() == cfg.l2OutputOracleChallenger()); require(oracle.CHALLENGER() == cfg.l2OutputOracleChallenger());
require(oracle.challenger() == cfg.l2OutputOracleChallenger());
require(oracle.FINALIZATION_PERIOD_SECONDS() == cfg.finalizationPeriodSeconds()); require(oracle.FINALIZATION_PERIOD_SECONDS() == cfg.finalizationPeriodSeconds());
require(oracle.finalizationPeriodSeconds() == cfg.finalizationPeriodSeconds());
require(oracle.startingBlockNumber() == cfg.l2OutputOracleStartingBlockNumber()); require(oracle.startingBlockNumber() == cfg.l2OutputOracleStartingBlockNumber());
require(oracle.startingTimestamp() == cfg.l2OutputOracleStartingTimestamp()); require(oracle.startingTimestamp() == cfg.l2OutputOracleStartingTimestamp());
} }
......
...@@ -14,19 +14,13 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -14,19 +14,13 @@ contract L2OutputOracle is Initializable, Semver {
/// @notice The interval in L2 blocks at which checkpoints must be submitted. /// @notice The interval in L2 blocks at which checkpoints must be submitted.
/// Although this is immutable, it can safely be modified by upgrading the /// Although this is immutable, it can safely be modified by upgrading the
/// implementation contract. /// implementation contract.
uint256 public immutable SUBMISSION_INTERVAL; uint256 internal immutable _SUBMISSION_INTERVAL;
/// @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified. /// @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified.
uint256 public immutable L2_BLOCK_TIME; uint256 internal immutable _L2_BLOCK_TIME;
/// @notice The address of the challenger. Can be updated via upgrade.
address public immutable CHALLENGER;
/// @notice The address of the proposer. Can be updated via upgrade.
address public immutable PROPOSER;
/// @notice The minimum time (in seconds) that must elapse before a withdrawal can be finalized. /// @notice The minimum time (in seconds) that must elapse before a withdrawal can be finalized.
uint256 public immutable FINALIZATION_PERIOD_SECONDS; uint256 internal immutable _FINALIZATION_PERIOD_SECONDS;
/// @notice The number of the first L2 block recorded in this contract. /// @notice The number of the first L2 block recorded in this contract.
uint256 public startingBlockNumber; uint256 public startingBlockNumber;
...@@ -37,6 +31,14 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -37,6 +31,14 @@ contract L2OutputOracle is Initializable, Semver {
/// @notice An array of L2 output proposals. /// @notice An array of L2 output proposals.
Types.OutputProposal[] internal l2Outputs; Types.OutputProposal[] internal l2Outputs;
/// @notice The address of the challenger. Can be updated via upgrade.
/// @custom:network-specific
address internal _CHALLENGER;
/// @notice The address of the proposer. Can be updated via upgrade.
/// @custom:network-specific
address internal _PROPOSER;
/// @notice Emitted when an output is proposed. /// @notice Emitted when an output is proposed.
/// @param outputRoot The output root. /// @param outputRoot The output root.
/// @param l2OutputIndex The index of the output in the l2Outputs array. /// @param l2OutputIndex The index of the output in the l2Outputs array.
...@@ -54,44 +56,48 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -54,44 +56,48 @@ contract L2OutputOracle is Initializable, Semver {
/// @param newNextOutputIndex Next L2 output index after the deletion. /// @param newNextOutputIndex Next L2 output index after the deletion.
event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex); event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);
/// @custom:semver 1.3.1 /// @custom:semver 1.4.0
/// @notice Constructs the L2OutputOracle contract. /// @notice Constructs the L2OutputOracle contract.
/// @param _submissionInterval Interval in blocks at which checkpoints must be submitted. /// @param _submissionInterval Interval in blocks at which checkpoints must be submitted.
/// @param _l2BlockTime The time per L2 block, in seconds. /// @param _l2BlockTime The time per L2 block, in seconds.
/// @param _startingBlockNumber The number of the first L2 block. /// @param _finalizationPeriodSeconds The amount of time that must pass for an output proposal to
/// @param _startingTimestamp The timestamp of the first L2 block. // be considered canonical.
/// @param _proposer The address of the proposer.
/// @param _challenger The address of the challenger.
constructor( constructor(
uint256 _submissionInterval, uint256 _submissionInterval,
uint256 _l2BlockTime, uint256 _l2BlockTime,
uint256 _startingBlockNumber,
uint256 _startingTimestamp,
address _proposer,
address _challenger,
uint256 _finalizationPeriodSeconds uint256 _finalizationPeriodSeconds
) Semver(1, 3, 1) { ) Semver(1, 4, 0) {
require(_l2BlockTime > 0, "L2OutputOracle: L2 block time must be greater than 0"); require(_l2BlockTime > 0, "L2OutputOracle: L2 block time must be greater than 0");
require( require(
_submissionInterval > 0, _submissionInterval > 0,
"L2OutputOracle: submission interval must be greater than 0" "L2OutputOracle: submission interval must be greater than 0"
); );
SUBMISSION_INTERVAL = _submissionInterval; _SUBMISSION_INTERVAL = _submissionInterval;
L2_BLOCK_TIME = _l2BlockTime; _L2_BLOCK_TIME = _l2BlockTime;
PROPOSER = _proposer; _FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;
CHALLENGER = _challenger;
FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;
initialize(_startingBlockNumber, _startingTimestamp); initialize({
_startingBlockNumber: 0,
_startingTimestamp: 0,
_proposer: address(0),
_challenger: address(0)
});
} }
/// @notice Initializer. /// @notice Initializer.
/// @param _startingBlockNumber Block number for the first recoded L2 block. /// @param _startingBlockNumber Block number for the first recoded L2 block.
/// @param _startingTimestamp Timestamp for the first recoded L2 block. /// @param _startingTimestamp Timestamp for the first recoded L2 block.
function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp) /// @param _proposer The address of the proposer.
/// @param _challenger The address of the challenger.
function initialize(
uint256 _startingBlockNumber,
uint256 _startingTimestamp,
address _proposer,
address _challenger
)
public public
initializer reinitializer(2)
{ {
require( require(
_startingTimestamp <= block.timestamp, _startingTimestamp <= block.timestamp,
...@@ -100,6 +106,64 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -100,6 +106,64 @@ contract L2OutputOracle is Initializable, Semver {
startingTimestamp = _startingTimestamp; startingTimestamp = _startingTimestamp;
startingBlockNumber = _startingBlockNumber; startingBlockNumber = _startingBlockNumber;
_PROPOSER = _proposer;
_CHALLENGER = _challenger;
}
/// @notice Getter for the output proposal submission interval.
/// @custom:legacy
function SUBMISSION_INTERVAL() external view returns (uint256) {
return _SUBMISSION_INTERVAL;
}
/// @notice Getter for the output proposal submission interval.
function submissionInterval() external view returns (uint256) {
return _SUBMISSION_INTERVAL;
}
/// @notice Getter for the L2 block time.
/// @custom:legacy
function L2_BLOCK_TIME() external view returns (uint256) {
return _L2_BLOCK_TIME;
}
/// @notice Getter for the L2 block time.
function l2BlockTime() external view returns (uint256) {
return _L2_BLOCK_TIME;
}
/// @notice Getter for the finalization period.
/// @custom:legacy
function FINALIZATION_PERIOD_SECONDS() external view returns (uint256) {
return _FINALIZATION_PERIOD_SECONDS;
}
/// @notice Getter for the finalization period.
function finalizationPeriodSeconds() external view returns (uint256) {
return _FINALIZATION_PERIOD_SECONDS;
}
/// @notice Getter for the challenger address.
/// @custom:legacy
function CHALLENGER() external view returns (address) {
return _CHALLENGER;
}
/// @notice Getter for the challenger address.
function challenger() external view returns (address) {
return _CHALLENGER;
}
/// @notice Getter for the proposer address.
/// @custom:legacy
function PROPOSER() external view returns (address) {
return _PROPOSER;
}
/// @notice Getter for the proposer address.
function proposer() external view returns (address) {
return _PROPOSER;
} }
/// @notice Deletes all output proposals after and including the proposal that corresponds to /// @notice Deletes all output proposals after and including the proposal that corresponds to
...@@ -109,7 +173,7 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -109,7 +173,7 @@ contract L2OutputOracle is Initializable, Semver {
// solhint-disable-next-line ordering // solhint-disable-next-line ordering
function deleteL2Outputs(uint256 _l2OutputIndex) external { function deleteL2Outputs(uint256 _l2OutputIndex) external {
require( require(
msg.sender == CHALLENGER, msg.sender == _CHALLENGER,
"L2OutputOracle: only the challenger address can delete outputs" "L2OutputOracle: only the challenger address can delete outputs"
); );
...@@ -121,7 +185,7 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -121,7 +185,7 @@ contract L2OutputOracle is Initializable, Semver {
// Do not allow deleting any outputs that have already been finalized. // Do not allow deleting any outputs that have already been finalized.
require( require(
block.timestamp - l2Outputs[_l2OutputIndex].timestamp < FINALIZATION_PERIOD_SECONDS, block.timestamp - l2Outputs[_l2OutputIndex].timestamp < _FINALIZATION_PERIOD_SECONDS,
"L2OutputOracle: cannot delete outputs that have already been finalized" "L2OutputOracle: cannot delete outputs that have already been finalized"
); );
...@@ -149,7 +213,7 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -149,7 +213,7 @@ contract L2OutputOracle is Initializable, Semver {
uint256 _l1BlockNumber uint256 _l1BlockNumber
) external payable { ) external payable {
require( require(
msg.sender == PROPOSER, msg.sender == _PROPOSER,
"L2OutputOracle: only the proposer address can propose new outputs" "L2OutputOracle: only the proposer address can propose new outputs"
); );
...@@ -278,13 +342,13 @@ contract L2OutputOracle is Initializable, Semver { ...@@ -278,13 +342,13 @@ contract L2OutputOracle is Initializable, Semver {
/// @notice Computes the block number of the next L2 block that needs to be checkpointed. /// @notice Computes the block number of the next L2 block that needs to be checkpointed.
/// @return Next L2 block number. /// @return Next L2 block number.
function nextBlockNumber() public view returns (uint256) { function nextBlockNumber() public view returns (uint256) {
return latestBlockNumber() + SUBMISSION_INTERVAL; return latestBlockNumber() + _SUBMISSION_INTERVAL;
} }
/// @notice Returns the L2 timestamp corresponding to a given L2 block number. /// @notice Returns the L2 timestamp corresponding to a given L2 block number.
/// @param _l2BlockNumber The L2 block number of the target block. /// @param _l2BlockNumber The L2 block number of the target block.
/// @return L2 timestamp of the given block. /// @return L2 timestamp of the given block.
function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) { function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {
return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * L2_BLOCK_TIME); return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * _L2_BLOCK_TIME);
} }
} }
...@@ -105,6 +105,7 @@ contract L2OutputOracle_Initializer is CommonTest { ...@@ -105,6 +105,7 @@ contract L2OutputOracle_Initializer is CommonTest {
uint256 internal l2BlockTime = 2; uint256 internal l2BlockTime = 2;
uint256 internal startingBlockNumber = 200; uint256 internal startingBlockNumber = 200;
uint256 internal startingTimestamp = 1000; uint256 internal startingTimestamp = 1000;
uint256 internal finalizationPeriodSeconds = 7 days;
address guardian; address guardian;
// Test data // Test data
...@@ -157,17 +158,21 @@ contract L2OutputOracle_Initializer is CommonTest { ...@@ -157,17 +158,21 @@ contract L2OutputOracle_Initializer is CommonTest {
oracleImpl = new L2OutputOracle({ oracleImpl = new L2OutputOracle({
_submissionInterval: submissionInterval, _submissionInterval: submissionInterval,
_l2BlockTime: l2BlockTime, _l2BlockTime: l2BlockTime,
_startingBlockNumber: startingBlockNumber, _finalizationPeriodSeconds: finalizationPeriodSeconds
_startingTimestamp: startingTimestamp,
_proposer: proposer,
_challenger: owner,
_finalizationPeriodSeconds: 7 days
}); });
Proxy proxy = new Proxy(multisig); Proxy proxy = new Proxy(multisig);
vm.prank(multisig); vm.prank(multisig);
proxy.upgradeToAndCall( proxy.upgradeToAndCall(
address(oracleImpl), address(oracleImpl),
abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp)) abi.encodeCall(
L2OutputOracle.initialize,
(
startingBlockNumber,
startingTimestamp,
proposer,
owner
)
)
); );
oracle = L2OutputOracle(address(proxy)); oracle = L2OutputOracle(address(proxy));
vm.label(address(oracle), "L2OutputOracle"); vm.label(address(oracle), "L2OutputOracle");
......
...@@ -18,27 +18,18 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { ...@@ -18,27 +18,18 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer {
/// @dev Tests that constructor sets the initial values correctly. /// @dev Tests that constructor sets the initial values correctly.
function test_constructor_succeeds() external { function test_constructor_succeeds() external {
assertEq(oracle.PROPOSER(), proposer); assertEq(oracle.PROPOSER(), proposer);
assertEq(oracle.proposer(), proposer);
assertEq(oracle.CHALLENGER(), owner); assertEq(oracle.CHALLENGER(), owner);
assertEq(oracle.challenger(), owner);
assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval); assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);
assertEq(oracle.submissionInterval(), submissionInterval);
assertEq(oracle.latestBlockNumber(), startingBlockNumber); assertEq(oracle.latestBlockNumber(), startingBlockNumber);
assertEq(oracle.startingBlockNumber(), startingBlockNumber); assertEq(oracle.startingBlockNumber(), startingBlockNumber);
assertEq(oracle.startingTimestamp(), startingTimestamp); assertEq(oracle.startingTimestamp(), startingTimestamp);
} assertEq(oracle.L2_BLOCK_TIME(), l2BlockTime);
assertEq(oracle.l2BlockTime(), l2BlockTime);
/// @dev Tests that the constructor reverts if the starting timestamp is invalid. assertEq(oracle.finalizationPeriodSeconds(), finalizationPeriodSeconds);
function test_constructor_badTimestamp_reverts() external { assertEq(oracle.FINALIZATION_PERIOD_SECONDS(), finalizationPeriodSeconds);
vm.expectRevert("L2OutputOracle: starting L2 timestamp must be less than current time");
// startingTimestamp is in the future
new L2OutputOracle({
_submissionInterval: submissionInterval,
_l2BlockTime: l2BlockTime,
_startingBlockNumber: startingBlockNumber,
_startingTimestamp: block.timestamp + 1,
_proposer: proposer,
_challenger: owner,
_finalizationPeriodSeconds: 7 days
});
} }
/// @dev Tests that the constructor reverts if the l2BlockTime is invalid. /// @dev Tests that the constructor reverts if the l2BlockTime is invalid.
...@@ -47,10 +38,6 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { ...@@ -47,10 +38,6 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer {
new L2OutputOracle({ new L2OutputOracle({
_submissionInterval: submissionInterval, _submissionInterval: submissionInterval,
_l2BlockTime: 0, _l2BlockTime: 0,
_startingBlockNumber: startingBlockNumber,
_startingTimestamp: block.timestamp,
_proposer: proposer,
_challenger: owner,
_finalizationPeriodSeconds: 7 days _finalizationPeriodSeconds: 7 days
}); });
} }
...@@ -61,13 +48,41 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { ...@@ -61,13 +48,41 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer {
new L2OutputOracle({ new L2OutputOracle({
_submissionInterval: 0, _submissionInterval: 0,
_l2BlockTime: l2BlockTime, _l2BlockTime: l2BlockTime,
_startingBlockNumber: startingBlockNumber,
_startingTimestamp: block.timestamp,
_proposer: proposer,
_challenger: owner,
_finalizationPeriodSeconds: 7 days _finalizationPeriodSeconds: 7 days
}); });
} }
/* For some reason, this test causes foundry to stack overflow
/// @dev Tests that the constructor reverts if the starting timestamp is invalid.
function test_constructor_badTimestamp_reverts() external {
Proxy proxy = new Proxy({
_admin: alice
});
vm.store(address(proxy), bytes32(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc), bytes32(uint256(uint160(address(oracle)))));
vm.expectRevert("L2OutputOracle: starting L2 timestamp must be less than current time");
proxy.upgradeToAndCall({
_implementation: address(oracle),
_data: abi.encodeCall(
L2OutputOracle.initialize,
(
0,
block.timestamp + 1,
address(0),
address(0)
)
)
});
L2OutputOracle(address(proxy)).initialize({
_startingBlockNumber: 0,
_startingTimestamp: block.timestamp + 1,
_proposer: address(0),
_challenger: address(0)
});
}
*/
} }
contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer { contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer {
...@@ -423,25 +438,54 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { ...@@ -423,25 +438,54 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
/// @dev Tests that the proxy is initialized with the correct values. /// @dev Tests that the proxy is initialized with the correct values.
function test_initValuesOnProxy_succeeds() external { function test_initValuesOnProxy_succeeds() external {
assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);
assertEq(oracle.submissionInterval(), submissionInterval);
assertEq(oracle.L2_BLOCK_TIME(), l2BlockTime);
assertEq(oracle.l2BlockTime(), l2BlockTime);
assertEq(oracle.startingBlockNumber(), startingBlockNumber);
assertEq(oracle.startingTimestamp(), startingTimestamp);
assertEq(oracle.finalizationPeriodSeconds(), finalizationPeriodSeconds);
assertEq(oracle.PROPOSER(), proposer);
assertEq(oracle.proposer(), proposer);
assertEq(oracle.CHALLENGER(), owner);
assertEq(oracle.challenger(), owner);
}
/// @dev Tests that the impl is created with the correct values.
function test_initValuesOnImpl_succeeds() external {
assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL()); assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL());
assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME()); assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME());
assertEq(startingBlockNumber, oracleImpl.startingBlockNumber());
assertEq(startingTimestamp, oracleImpl.startingTimestamp());
assertEq(proposer, oracleImpl.PROPOSER()); // The values that are set in the initialize function should be all
assertEq(owner, oracleImpl.CHALLENGER()); // zero values in the implementation contract.
assertEq(oracleImpl.startingBlockNumber(), 0);
assertEq(oracleImpl.startingTimestamp(), 0);
assertEq(oracleImpl.PROPOSER(), address(0));
assertEq(oracleImpl.proposer(), address(0));
assertEq(oracleImpl.CHALLENGER(), address(0));
assertEq(oracleImpl.challenger(), address(0));
} }
/// @dev Tests that the proxy cannot be initialized twice. /// @dev Tests that the proxy cannot be initialized twice.
function test_initializeProxy_alreadyInitialized_reverts() external { function test_initializeProxy_alreadyInitialized_reverts() external {
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
L2OutputOracle(payable(proxy)).initialize(startingBlockNumber, startingTimestamp); L2OutputOracle(payable(proxy)).initialize({
_startingBlockNumber: startingBlockNumber,
_startingTimestamp: startingTimestamp,
_proposer: address(1),
_challenger: address(2)
});
} }
/// @dev Tests that the implementation contract cannot be initialized twice. /// @dev Tests that the implementation contract cannot be initialized twice.
function test_initializeImpl_alreadyInitialized_reverts() external { function test_initializeImpl_alreadyInitialized_reverts() external {
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
L2OutputOracle(oracleImpl).initialize(startingBlockNumber, startingTimestamp); L2OutputOracle(oracleImpl).initialize({
_startingBlockNumber: startingBlockNumber,
_startingTimestamp: startingTimestamp,
_proposer: address(1),
_challenger: address(2)
});
} }
/// @dev Tests that the proxy can be successfully upgraded. /// @dev Tests that the proxy can be successfully upgraded.
...@@ -454,7 +498,7 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { ...@@ -454,7 +498,7 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
vm.startPrank(multisig); vm.startPrank(multisig);
proxy.upgradeToAndCall( proxy.upgradeToAndCall(
address(nextImpl), address(nextImpl),
abi.encodeWithSelector(NextImpl.initialize.selector, 2) abi.encodeWithSelector(NextImpl.initialize.selector, 3)
); );
assertEq(proxy.implementation(), address(nextImpl)); assertEq(proxy.implementation(), address(nextImpl));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment