Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
01fbb00a
Commit
01fbb00a
authored
Jun 22, 2023
by
Andreas Bigger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More styling fixes
parent
26f536dc
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
153 additions
and
132 deletions
+153
-132
OptimismPortal.t.sol
...ges/contracts-bedrock/contracts/test/OptimismPortal.t.sol
+87
-89
ResourceMetering.t.sol
...s/contracts-bedrock/contracts/test/ResourceMetering.t.sol
+38
-41
SystemConfig.t.sol
packages/contracts-bedrock/contracts/test/SystemConfig.t.sol
+28
-2
No files found.
packages/contracts-bedrock/contracts/test/OptimismPortal.t.sol
View file @
01fbb00a
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { stdError } from "forge-std/Test.sol";
import { Portal_Initializer, CommonTest, NextImpl } from "./CommonTest.t.sol";
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { OptimismPortal } from "../L1/OptimismPortal.sol";
// Libraries
import { Types } from "../libraries/Types.sol";
import { Hashing } from "../libraries/Hashing.sol";
// Target contract dependencies
import { Proxy } from "../universal/Proxy.sol";
import { ResourceMetering } from "../L1/ResourceMetering.sol";
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
// Target contract
import { OptimismPortal } from "../L1/OptimismPortal.sol";
contract OptimismPortal_Test is Portal_Initializer {
event Paused(address);
event Unpaused(address);
/// @dev Tests that the constructor sets the correct values.
function test_constructor_succeeds() external {
assertEq(address(op.L2_ORACLE()), address(oracle));
assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD);
assertEq(op.paused(), false);
}
/**
* @notice The OptimismPortal can be paused by the GUARDIAN
*/
/// @dev Tests that `pause` successfully pauses
/// when called by the GUARDIAN.
function test_pause_succeeds() external {
address guardian = op.GUARDIAN();
...
...
@@ -38,10 +45,7 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(op.paused(), true);
}
/**
* @notice The OptimismPortal reverts when an account that is not the
* GUARDIAN calls `pause()`
*/
/// @dev Tests that `pause` reverts when called by a non-GUARDIAN.
function test_pause_onlyGuardian_reverts() external {
assertEq(op.paused(), false);
...
...
@@ -53,9 +57,8 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(op.paused(), false);
}
/**
* @notice The OptimismPortal can be unpaused by the GUARDIAN
*/
/// @dev Tests that `unpause` successfully unpauses
/// when called by the GUARDIAN.
function test_unpause_succeeds() external {
address guardian = op.GUARDIAN();
...
...
@@ -71,10 +74,7 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(op.paused(), false);
}
/**
* @notice The OptimismPortal reverts when an account that is not
* the GUARDIAN calls `unpause()`
*/
/// @dev Tests that `unpause` reverts when called by a non-GUARDIAN.
function test_unpause_onlyGuardian_reverts() external {
address guardian = op.GUARDIAN();
...
...
@@ -90,6 +90,7 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(op.paused(), true);
}
/// @dev Tests that `receive` successdully deposits ETH.
function test_receive_succeeds() external {
vm.expectEmit(true, true, false, true);
emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex"");
...
...
@@ -103,17 +104,16 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(address(op).balance, 100);
}
// Test: depositTransaction fails when contract creation has a non-zero destination address
/// @dev Tests that `depositTransaction` reverts when the destination address is non-zero
/// for a contract creation deposit.
function test_depositTransaction_contractCreation_reverts() external {
// contract creation must have a target of address(0)
vm.expectRevert("OptimismPortal: must send to address(0) when creating a contract");
op.depositTransaction(address(1), 1, 0, true, hex"");
}
/**
* @notice Prevent deposits from being too large to have a sane upper bound
* on unsafe blocks sent over the p2p network.
*/
/// @dev Tests that `depositTransaction` reverts when the data is too large.
/// This places an upper bound on unsafe blocks sent over p2p.
function test_depositTransaction_largeData_reverts() external {
uint256 size = 120_001;
uint64 gasLimit = op.minimumGasLimit(uint64(size));
...
...
@@ -127,10 +127,7 @@ contract OptimismPortal_Test is Portal_Initializer {
});
}
/**
* @notice Prevent gasless deposits from being force processed in L2 by
* ensuring that they have a large enough gas limit set.
*/
/// @dev Tests that `depositTransaction` reverts when the gas limit is too small.
function test_depositTransaction_smallGasLimit_reverts() external {
vm.expectRevert("OptimismPortal: gas limit too small");
op.depositTransaction({
...
...
@@ -142,9 +139,8 @@ contract OptimismPortal_Test is Portal_Initializer {
});
}
/**
* @notice Fuzz for too small of gas limits
*/
/// @dev Tests that `depositTransaction` succeeds for small,
/// but sufficient, gas limits.
function testFuzz_depositTransaction_smallGasLimit_succeeds(
bytes memory _data,
bool _shouldFail
...
...
@@ -166,17 +162,16 @@ contract OptimismPortal_Test is Portal_Initializer {
});
}
/**
* @notice Ensure that the 0 calldata case is covered and there is a linearly
* increasing gas limit for larger calldata sizes.
*/
/// @dev Tests that `minimumGasLimit` succeeds for small calldata sizes.
/// The gas limit should be 21k for 0 calldata and increase linearly
/// for larger calldata sizes.
function test_minimumGasLimit_succeeds() external {
assertEq(op.minimumGasLimit(0), 21_000);
assertTrue(op.minimumGasLimit(2) > op.minimumGasLimit(1));
assertTrue(op.minimumGasLimit(3) > op.minimumGasLimit(2));
}
//
Test: depositTransaction should emit the correct log when an EOA deposits a tx with 0 value
//
/ @dev Tests that `depositTransaction` succeeds for an EOA depositing a tx with 0 value.
function test_depositTransaction_noValueEOA_succeeds() external {
// EOA emulation
vm.prank(address(this), address(this));
...
...
@@ -200,7 +195,7 @@ contract OptimismPortal_Test is Portal_Initializer {
);
}
//
Test: depositTransaction should emit the correct log when a contract deposits a tx with 0 value
//
/ @dev Tests that `depositTransaction` succeeds for a contract depositing a tx with 0 value.
function test_depositTransaction_noValueContract_succeeds() external {
vm.expectEmit(true, true, false, true);
emitTransactionDeposited(
...
...
@@ -222,7 +217,8 @@ contract OptimismPortal_Test is Portal_Initializer {
);
}
// Test: depositTransaction should emit the correct log when an EOA deposits a contract creation with 0 value
/// @dev Tests that `depositTransaction` succeeds for an EOA
/// depositing a contract creation with 0 value.
function test_depositTransaction_createWithZeroValueForEOA_succeeds() external {
// EOA emulation
vm.prank(address(this), address(this));
...
...
@@ -241,7 +237,8 @@ contract OptimismPortal_Test is Portal_Initializer {
op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);
}
// Test: depositTransaction should emit the correct log when a contract deposits a contract creation with 0 value
/// @dev Tests that `depositTransaction` succeeds for a contract
/// depositing a contract creation with 0 value.
function test_depositTransaction_createWithZeroValueForContract_succeeds() external {
vm.expectEmit(true, true, false, true);
emitTransactionDeposited(
...
...
@@ -257,7 +254,7 @@ contract OptimismPortal_Test is Portal_Initializer {
op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);
}
//
Test: depositTransaction should increase its eth balance when an EOA deposits a transaction with ETH
//
/ @dev Tests that `depositTransaction` succeeds for an EOA depositing a tx with ETH.
function test_depositTransaction_withEthValueFromEOA_succeeds() external {
// EOA emulation
vm.prank(address(this), address(this));
...
...
@@ -283,7 +280,7 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(address(op).balance, NON_ZERO_VALUE);
}
//
Test: depositTransaction should increase its eth balance when a contract deposits a transaction with ETH
//
/ @dev Tests that `depositTransaction` succeeds for a contract depositing a tx with ETH.
function test_depositTransaction_withEthValueFromContract_succeeds() external {
vm.expectEmit(true, true, false, true);
emitTransactionDeposited(
...
...
@@ -305,7 +302,7 @@ contract OptimismPortal_Test is Portal_Initializer {
);
}
//
Test: depositTransaction should increase its eth balance when an EOA deposits a contract creation with ETH
//
/ @dev Tests that `depositTransaction` succeeds for an EOA depositing a contract creation with ETH.
function test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() external {
// EOA emulation
vm.prank(address(this), address(this));
...
...
@@ -331,7 +328,7 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(address(op).balance, NON_ZERO_VALUE);
}
//
Test: depositTransaction should increase its eth balance when a contract deposits a contract creation with ETH
//
/ @dev Tests that `depositTransaction` succeeds for a contract depositing a contract creation with ETH.
function test_depositTransaction_withEthValueAndContractContractCreation_succeeds() external {
vm.expectEmit(true, true, false, true);
emitTransactionDeposited(
...
...
@@ -354,6 +351,7 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(address(op).balance, NON_ZERO_VALUE);
}
/// @dev Tests that `isOutputFinalized` succeeds for an EOA depositing a tx with ETH and data.
function test_simple_isOutputFinalized_succeeds() external {
uint256 ts = block.timestamp;
vm.mockCall(
...
...
@@ -373,6 +371,7 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(op.isOutputFinalized(0), true);
}
/// @dev Tests `isOutputFinalized` for a finalized output.
function test_isOutputFinalized_succeeds() external {
uint256 checkpoint = oracle.nextBlockNumber();
uint256 nextOutputIndex = oracle.nextOutputIndex();
...
...
@@ -439,7 +438,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
_proposedOutputIndex = oracle.nextOutputIndex();
}
//
Get the system into a nice
ready-to-use state.
//
/ @dev Setup the system for a
ready-to-use state.
function setUp() public override {
// Configure the oracle to return the output root we've prepared.
vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);
...
...
@@ -456,8 +455,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.deal(address(op), 0xFFFFFFFF);
}
// Utility function used in the subsequent test. This is necessary to assert that the
// reentrant call will revert.
/// @dev Asserts that the reentrant call will revert.
function callPortalAndExpectRevert() external payable {
vm.expectRevert("OptimismPortal: can only trigger one withdrawal per transaction");
// Arguments here don't matter, as the require check is the first thing that happens.
...
...
@@ -467,9 +465,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx)));
}
/**
* @notice Proving withdrawal transactions should revert when paused
*/
/// @dev Tests that `proveWithdrawalTransaction` reverts when paused.
function test_proveWithdrawalTransaction_paused_reverts() external {
vm.prank(op.GUARDIAN());
op.pause();
...
...
@@ -483,7 +479,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
});
}
//
Test: proveWithdrawalTransaction cannot prove a withdrawal with itself (the OptimismPortal) as the targe
t.
//
/ @dev Tests that `proveWithdrawalTransaction` reverts when the target is the portal contrac
t.
function test_proveWithdrawalTransaction_onSelfCall_reverts() external {
_defaultTx.target = address(op);
vm.expectRevert("OptimismPortal: you cannot send messages to the portal contract");
...
...
@@ -495,7 +491,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
);
}
// Test: proveWithdrawalTransaction reverts if the outputRootProof does not match the output root
/// @dev Tests that `proveWithdrawalTransaction` reverts when
/// the outputRootProof does not match the output root
function test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() external {
// Modify the version to invalidate the withdrawal proof.
_outputRootProof.version = bytes32(uint256(1));
...
...
@@ -508,8 +505,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
);
}
// Test: proveWithdrawalTransaction reverts if the proof is invalid due to non-existence of
// the withdrawal.
/// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal is missing.
function test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() external {
// modify the default test values to invalidate the proof.
_defaultTx.data = hex"abcd";
...
...
@@ -522,8 +518,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
);
}
//
Test: proveWithdrawalTransaction reverts if the passed transaction's withdrawalHash has
//
already
been proven.
//
/ @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal has already
//
/
been proven.
function test_proveWithdrawalTransaction_replayProve_reverts() external {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
...
...
@@ -543,8 +539,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
);
}
//
Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has
//
already been proven AND the output root has changed AND
the l2BlockNumber stays the same.
//
/ @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already
//
/ been proven and the output root has changed and
the l2BlockNumber stays the same.
function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
...
...
@@ -587,8 +583,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
assertEq(timestamp, block.timestamp);
}
//
Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has
//
already been proven AND the output root + output index + l2BlockNumber changes
.
//
/ @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already
//
/ been proven and the output root, output index, and l2BlockNumber have changed
.
function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds()
external
{
...
...
@@ -646,7 +642,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
assertEq(timestamp, block.timestamp);
}
//
Test: proveWithdrawalTransaction succeeds and emits the WithdrawalProven event
.
//
/ @dev Tests that `proveWithdrawalTransaction` succeeds
.
function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
...
...
@@ -658,7 +654,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
);
}
//
Test: finalizeWithdrawalTransaction succeeds and emits the WithdrawalFinalized event
.
//
/ @dev Tests that `finalizeWithdrawalTransaction` succeeds
.
function test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() external {
uint256 bobBalanceBefore = address(bob).balance;
...
...
@@ -679,9 +675,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
assert(address(bob).balance == bobBalanceBefore + 100);
}
/**
* @notice Finalizing withdrawal transactions should revert when paused
*/
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the contract is paused.
function test_finalizeWithdrawalTransaction_paused_reverts() external {
vm.prank(op.GUARDIAN());
op.pause();
...
...
@@ -690,7 +684,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
op.finalizeWithdrawalTransaction(_defaultTx);
}
//
Test: finalizeWithdrawalTransaction reverts if the withdrawal has not been proven.
//
/ @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has not been
function test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() external {
uint256 bobBalanceBefore = address(bob).balance;
...
...
@@ -700,7 +694,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
assert(address(bob).balance == bobBalanceBefore);
}
// Test: finalizeWithdrawalTransaction reverts if withdrawal not proven long enough ago.
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has not been
/// proven long enough ago.
function test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() external {
uint256 bobBalanceBefore = address(bob).balance;
...
...
@@ -727,8 +722,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
assert(address(bob).balance == bobBalanceBefore);
}
//
Test: finalizeWithdrawalTransaction reverts if the provenWithdrawal's timestamp is less
//
than the L2 output oracle's starting timestamp
//
/ @dev Tests that `finalizeWithdrawalTransaction` reverts if the provenWithdrawal's timestamp
//
/ is less than the L2 output oracle's starting timestamp.
function test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() external {
uint256 bobBalanceBefore = address(bob).balance;
...
...
@@ -762,8 +757,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
assertEq(bobBalanceBefore, address(bob).balance);
}
//
Test: finalizeWithdrawalTransaction reverts if the output root proven is not the same as
the
// output root at the time of finalization.
//
/ @dev Tests that `finalizeWithdrawalTransaction` reverts if the output root proven is not
the
//
/ same as the
output root at the time of finalization.
function test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() external {
uint256 bobBalanceBefore = address(bob).balance;
...
...
@@ -804,8 +799,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
assertEq(bobBalanceBefore, address(bob).balance);
}
//
Test: finalizeWithdrawalTransaction reverts if the output proposal's timestamp has
// not passed the finalization period.
//
/ @dev Tests that `finalizeWithdrawalTransaction` reverts if the output proposal's timestamp
//
/ has
not passed the finalization period.
function test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() external {
uint256 bobBalanceBefore = address(bob).balance;
...
...
@@ -844,8 +839,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
assertEq(bobBalanceBefore, address(bob).balance);
}
// Test: finalizeWithdrawalTransaction fails because the target reverts,
// and emits the WithdrawalFinalized event with success=false.
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the target reverts.
function test_finalizeWithdrawalTransaction_targetFails_fails() external {
uint256 bobBalanceBefore = address(bob).balance;
vm.etch(bob, hex"fe"); // Contract with just the invalid opcode.
...
...
@@ -867,7 +861,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
assert(address(bob).balance == bobBalanceBefore);
}
// Test: finalizeWithdrawalTransaction reverts if the finalization period has not yet passed.
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the finalization period
/// has not yet passed.
function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external {
// Setup the Oracle to return an output with a recent timestamp
uint256 recentTimestamp = block.timestamp - 1000;
...
...
@@ -894,7 +889,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
op.finalizeWithdrawalTransaction(_defaultTx);
}
// Test: finalizeWithdrawalTransaction reverts if the withdrawal has already been finalized.
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has already been
/// finalized.
function test_finalizeWithdrawalTransaction_onReplay_reverts() external {
vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob);
...
...
@@ -914,7 +910,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
op.finalizeWithdrawalTransaction(_defaultTx);
}
// Test: finalizeWithdrawalTransaction reverts if insufficient gas is supplied.
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal transaction
/// does not have enough gas to execute.
function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external {
// This number was identified through trial and error.
uint256 gasLimit = 150_000;
...
...
@@ -961,8 +958,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx);
}
//
Test: finalizeWithdrawalTransaction reverts if a sub-call attempts to finalize another
// withdrawal.
//
/ @dev Tests that `finalizeWithdrawalTransaction` reverts if a sub-call attempts to finalize
//
/ another
withdrawal.
function test_finalizeWithdrawalTransaction_onReentrancy_reverts() external {
uint256 bobBalanceBefore = address(bob).balance;
...
...
@@ -1020,6 +1017,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
assert(address(bob).balance == bobBalanceBefore);
}
/// @dev Tests that `finalizeWithdrawalTransaction` succeeds.
function testDiff_finalizeWithdrawalTransaction_succeeds(
address _sender,
address _target,
...
...
@@ -1101,12 +1099,14 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer {
Proxy internal proxy;
uint64 initialBlockNum;
/// @dev Sets up the test.
function setUp() public override {
super.setUp();
initialBlockNum = uint64(block.number);
proxy = Proxy(payable(address(op)));
}
/// @dev Tests that the proxy is initialized correctly.
function test_params_initValuesOnProxy_succeeds() external {
OptimismPortal p = OptimismPortal(payable(address(proxy)));
...
...
@@ -1118,16 +1118,19 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer {
assertEq(prevBlockNum, initialBlockNum);
}
/// @dev Tests that the proxy cannot be initialized twice.
function test_initialize_cannotInitProxy_reverts() external {
vm.expectRevert("Initializable: contract is already initialized");
OptimismPortal(payable(proxy)).initialize(false);
}
/// @dev Tests that the implementation cannot be initialized twice.
function test_initialize_cannotInitImpl_reverts() external {
vm.expectRevert("Initializable: contract is already initialized");
OptimismPortal(opImpl).initialize(false);
}
/// @dev Tests that the proxy can be upgraded.
function test_upgradeToAndCall_upgrading_succeeds() external {
// Check an unused slot before upgrading.
bytes32 slot21Before = vm.load(address(op), bytes32(uint256(21)));
...
...
@@ -1148,21 +1151,16 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer {
}
}
/**
* @title OptimismPortalResourceFuzz_Test
* @dev Test various values of the resource metering config to ensure that deposits cannot be
* broken by changing the config.
*/
/// @title OptimismPortalResourceFuzz_Test
/// @dev Test various values of the resource metering config to ensure that deposits cannot be
/// broken by changing the config.
contract OptimismPortalResourceFuzz_Test is Portal_Initializer {
/**
* @dev The max gas limit observed throughout this test. Setting this too high can cause
* the test to take too long to run.
*/
/// @dev The max gas limit observed throughout this test. Setting this too high can cause
/// the test to take too long to run.
uint256 constant MAX_GAS_LIMIT = 30_000_000;
/**
* @dev Test that various values of the resource metering config will not break deposits.
*/
/// @dev Test that various values of the resource metering config will not break deposits.
function testFuzz_systemConfigDeposit_succeeds(
uint32 _maxResourceLimit,
uint8 _elasticityMultiplier,
...
...
packages/contracts-bedrock/contracts/test/ResourceMetering.t.sol
View file @
01fbb00a
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { Test } from "forge-std/Test.sol";
import { ResourceMetering } from "../L1/ResourceMetering.sol";
import { Proxy } from "../universal/Proxy.sol";
// Libraries
import { Constants } from "../libraries/Constants.sol";
// Target contract dependencies
import { Proxy } from "../universal/Proxy.sol";
// Target contract
import { ResourceMetering } from "../L1/ResourceMetering.sol";
contract MeterUser is ResourceMetering {
ResourceMetering.ResourceConfig public innerConfig;
...
...
@@ -50,20 +57,20 @@ contract MeterUser is ResourceMetering {
}
}
/**
* @title ResourceConfig
* @notice The tests are based on the default config values. It is expected that
* the config values used in these tests are ran in production.
*/
/// @title ResourceMetering_Test
/// @dev Tests are based on the default config values.
/// It is expected that these config values are used in production.
contract ResourceMetering_Test is Test {
MeterUser internal meter;
uint64 initialBlockNum;
/// @dev Sets up the test contract.
function setUp() public {
meter = new MeterUser();
initialBlockNum = uint64(block.number);
}
/// @dev Tests that the initial resource params are set correctly.
function test_meter_initialResourceParams_succeeds() external {
(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();
ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();
...
...
@@ -73,6 +80,7 @@ contract ResourceMetering_Test is Test {
assertEq(prevBlockNum, initialBlockNum);
}
/// @dev Tests that updating the resource params to the same values works correctly.
function test_meter_updateParamsNoChange_succeeds() external {
meter.use(0); // equivalent to just updating the base fee and block number
(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();
...
...
@@ -84,6 +92,7 @@ contract ResourceMetering_Test is Test {
assertEq(postBlockNum, prevBlockNum);
}
/// @dev Tests that updating the initial block number sets the meter params correctly.
function test_meter_updateOneEmptyBlock_succeeds() external {
vm.roll(initialBlockNum + 1);
meter.use(0);
...
...
@@ -94,6 +103,7 @@ contract ResourceMetering_Test is Test {
assertEq(prevBlockNum, initialBlockNum + 1);
}
/// @dev Tests that updating the initial block number sets the meter params correctly.
function test_meter_updateTwoEmptyBlocks_succeeds() external {
vm.roll(initialBlockNum + 2);
meter.use(0);
...
...
@@ -104,6 +114,7 @@ contract ResourceMetering_Test is Test {
assertEq(prevBlockNum, initialBlockNum + 2);
}
/// @dev Tests that updating the initial block number sets the meter params correctly.
function test_meter_updateTenEmptyBlocks_succeeds() external {
vm.roll(initialBlockNum + 10);
meter.use(0);
...
...
@@ -114,6 +125,7 @@ contract ResourceMetering_Test is Test {
assertEq(prevBlockNum, initialBlockNum + 10);
}
/// @dev Tests that updating the gas delta sets the meter params correctly.
function test_meter_updateNoGasDelta_succeeds() external {
ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();
uint256 target = uint256(rcfg.maxResourceLimit) / uint256(rcfg.elasticityMultiplier);
...
...
@@ -125,6 +137,7 @@ contract ResourceMetering_Test is Test {
assertEq(prevBlockNum, initialBlockNum);
}
/// @dev Tests that the meter params are set correctly for the maximum gas delta.
function test_meter_useMax_succeeds() external {
ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();
uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);
...
...
@@ -141,15 +154,9 @@ contract ResourceMetering_Test is Test {
assertEq(postBaseFee, 2125000000);
}
/**
* @notice This tests that the metered modifier reverts if
* the ResourceConfig baseFeeMaxChangeDenominator
* is set to 1.
* Since the metered modifier internally calls
* solmate's powWad function, it will revert
* with the error string "UNDEFINED" since the
* first parameter will be computed as 0.
*/
/// @dev Tests that the metered modifier reverts if the baseFeeMaxChangeDenominator is set to 1.
/// Since the metered modifier internally calls solmate's powWad function, it will revert
/// with the error string "UNDEFINED" since the first parameter will be computed as 0.
function test_meter_denominatorEq1_reverts() external {
ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();
uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);
...
...
@@ -167,6 +174,7 @@ contract ResourceMetering_Test is Test {
meter.use(0);
}
/// @dev Tests that the metered modifier reverts if the value is greater than allowed.
function test_meter_useMoreThanMax_reverts() external {
ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();
uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);
...
...
@@ -176,8 +184,7 @@ contract ResourceMetering_Test is Test {
meter.use(target * elasticityMultiplier + 1);
}
// Demonstrates that the resource metering arithmetic can tolerate very large gaps between
// deposits.
/// @dev Tests that resource metering can handle large gaps between deposits.
function testFuzz_meter_largeBlockDiff_succeeds(uint64 _amount, uint256 _blockDiff) external {
// This test fails if the following line is commented out.
// At 12 seconds per block, this number is effectively unreachable.
...
...
@@ -193,11 +200,9 @@ contract ResourceMetering_Test is Test {
}
}
/**
* @title CustomMeterUser
* @notice A simple wrapper around `ResourceMetering` that allows the initial
* params to be set in the constructor.
*/
/// @title CustomMeterUser
/// @notice A simple wrapper around `ResourceMetering` that allows the initial
/// params to be set in the constructor.
contract CustomMeterUser is ResourceMetering {
uint256 public startGas;
uint256 public endGas;
...
...
@@ -230,15 +235,13 @@ contract CustomMeterUser is ResourceMetering {
}
}
/**
* @title ArtifactResourceMetering_Test
* @notice A table test that sets the state of the ResourceParams and then requests
* various amounts of gas. This test ensures that a wide range of values
* can safely be used with the `ResourceMetering` contract.
* It also writes a CSV file to disk that includes useful information
* about how much gas is used and how expensive it is in USD terms to
* purchase the deposit gas.
*/
/// @title ArtifactResourceMetering_Test
/// @notice A table test that sets the state of the ResourceParams and then requests
/// various amounts of gas. This test ensures that a wide range of values
/// can safely be used with the `ResourceMetering` contract.
/// It also writes a CSV file to disk that includes useful information
/// about how much gas is used and how expensive it is in USD terms to
/// purchase the deposit gas.
contract ArtifactResourceMetering_Test is Test {
uint128 internal minimumBaseFee;
uint128 internal maximumBaseFee;
...
...
@@ -257,10 +260,7 @@ contract ArtifactResourceMetering_Test is Test {
bytes32 internal emptyReturnData =
0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
/**
* @notice Sets up the tests by getting constants from the ResourceMetering
* contract.
*/
/// @dev Sets up the tests with constants from the ResourceMetering contract.
function setUp() public {
vm.roll(1_000_000);
...
...
@@ -275,11 +275,8 @@ contract ArtifactResourceMetering_Test is Test {
try vm.removeFile(outfile) {} catch {}
}
/**
* @notice Generate a CSV file. The call to `meter` should be called with at
* most the L1 block gas limit. Without specifying the amount of
* gas, it can take very long to execute.
*/
/// @dev Generates a CSV file. No more than the L1 block gas limit should
/// be supplied to the `meter` function to avoid long execution time.
function test_meter_generateArtifact_succeeds() external {
vm.writeLine(
outfile,
...
...
packages/contracts-bedrock/contracts/test/SystemConfig.t.sol
View file @
01fbb00a
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
import { SystemConfig } from "../L1/SystemConfig.sol";
import { ResourceMetering } from "../L1/ResourceMetering.sol";
// Libraries
import { Constants } from "../libraries/Constants.sol";
// Target contract dependencies
import { ResourceMetering } from "../L1/ResourceMetering.sol";
// Target contract
import { SystemConfig } from "../L1/SystemConfig.sol";
contract SystemConfig_Init is CommonTest {
SystemConfig sysConf;
...
...
@@ -34,6 +41,8 @@ contract SystemConfig_Init is CommonTest {
}
contract SystemConfig_Initialize_TestFail is SystemConfig_Init {
/// @dev Tests that initialization reverts if the gas limit is too low.
function test_initialize_lowGasLimit_reverts() external {
uint64 minimumGasLimit = sysConf.minimumGasLimit();
...
...
@@ -60,32 +69,40 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Init {
}
contract SystemConfig_Setters_TestFail is SystemConfig_Init {
/// @dev Tests that `setBatcherHash` reverts if the caller is not the owner.
function test_setBatcherHash_notOwner_reverts() external {
vm.expectRevert("Ownable: caller is not the owner");
sysConf.setBatcherHash(bytes32(hex""));
}
/// @dev Tests that `setGasConfig` reverts if the caller is not the owner.
function test_setGasConfig_notOwner_reverts() external {
vm.expectRevert("Ownable: caller is not the owner");
sysConf.setGasConfig(0, 0);
}
/// @dev Tests that `setGasLimit` reverts if the caller is not the owner.
function test_setGasLimit_notOwner_reverts() external {
vm.expectRevert("Ownable: caller is not the owner");
sysConf.setGasLimit(0);
}
/// @dev Tests that `setUnsafeBlockSigner` reverts if the caller is not the owner.
function test_setUnsafeBlockSigner_notOwner_reverts() external {
vm.expectRevert("Ownable: caller is not the owner");
sysConf.setUnsafeBlockSigner(address(0x20));
}
/// @dev Tests that `setResourceConfig` reverts if the caller is not the owner.
function test_setResourceConfig_notOwner_reverts() external {
ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();
vm.expectRevert("Ownable: caller is not the owner");
sysConf.setResourceConfig(config);
}
/// @dev Tests that `setResourceConfig` reverts if the min base fee
/// is greater than the maximum allowed base fee.
function test_setResourceConfig_badMinMax_reverts() external {
ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({
maxResourceLimit: 20_000_000,
...
...
@@ -100,6 +117,8 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init {
sysConf.setResourceConfig(config);
}
/// @dev Tests that `setResourceConfig` reverts if the baseFeeMaxChangeDenominator
/// is zero.
function test_setResourceConfig_zeroDenominator_reverts() external {
ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({
maxResourceLimit: 20_000_000,
...
...
@@ -114,6 +133,7 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init {
sysConf.setResourceConfig(config);
}
/// @dev Tests that `setResourceConfig` reverts if the gas limit is too low.
function test_setResourceConfig_lowGasLimit_reverts() external {
uint64 gasLimit = sysConf.gasLimit();
...
...
@@ -130,6 +150,8 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init {
sysConf.setResourceConfig(config);
}
/// @dev Tests that `setResourceConfig` reverts if the elasticity multiplier
/// and max resource limit are configured such that there is a loss of precision.
function test_setResourceConfig_badPrecision_reverts() external {
ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({
maxResourceLimit: 20_000_000,
...
...
@@ -152,6 +174,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
bytes data
);
/// @dev Tests that `setBatcherHash` updates the batcher hash successfully.
function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external {
vm.expectEmit(true, true, true, true);
emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash));
...
...
@@ -161,6 +184,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
assertEq(sysConf.batcherHash(), newBatcherHash);
}
/// @dev Tests that `setGasConfig` updates the overhead and scalar successfully.
function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external {
vm.expectEmit(true, true, true, true);
emit ConfigUpdate(
...
...
@@ -175,6 +199,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
assertEq(sysConf.scalar(), newScalar);
}
/// @dev Tests that `setGasLimit` updates the gas limit successfully.
function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external {
uint64 minimumGasLimit = sysConf.minimumGasLimit();
newGasLimit = uint64(
...
...
@@ -189,6 +214,7 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
assertEq(sysConf.gasLimit(), newGasLimit);
}
/// @dev Tests that `setUnsafeBlockSigner` updates the block signer successfully.
function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external {
vm.expectEmit(true, true, true, true);
emit ConfigUpdate(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment