Commit 01fbb00a authored by Andreas Bigger's avatar Andreas Bigger

More styling fixes

parent 26f536dc
// 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 target.
/// @dev Tests that `proveWithdrawalTransaction` reverts when the target is the portal contract.
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,
......
// 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,
......
// 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(
......
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