Commit 57413031 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #7928 from ethereum-optimism/feat/ctb-test-deploy-2

contracts-bedrock: test deploy script
parents 202db3ae cef1a244
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -59,4 +59,3 @@ runs = 512
[profile.lite]
optimizer = false
# `CrossDomainMessenger` Invariants
## A call to `relayMessage` should succeed if at least the minimum gas limit can be supplied to the target context, there is enough gas to complete execution of `relayMessage` after the target context's execution is finished, and the target context did not revert.
**Test:** [`CrossDomainMessenger.t.sol#L136`](../test/invariants/CrossDomainMessenger.t.sol#L136)
**Test:** [`CrossDomainMessenger.t.sol#L137`](../test/invariants/CrossDomainMessenger.t.sol#L137)
There are two minimum gas limits here:
- The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit.
- The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target contract.
## A call to `relayMessage` should assign the message hash to the `failedMessages` mapping if not enough gas is supplied to forward `minGasLimit` to the target context or if there is not enough gas to complete execution of `relayMessage` after the target context's execution is finished.
**Test:** [`CrossDomainMessenger.t.sol#L169`](../test/invariants/CrossDomainMessenger.t.sol#L169)
**Test:** [`CrossDomainMessenger.t.sol#L170`](../test/invariants/CrossDomainMessenger.t.sol#L170)
There are two minimum gas limits here:
- The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit.
......
# `OptimismPortal` Invariants
## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`.
**Test:** [`OptimismPortal.t.sol#L148`](../test/invariants/OptimismPortal.t.sol#L148)
**Test:** [`OptimismPortal.t.sol#L151`](../test/invariants/OptimismPortal.t.sol#L151)
All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed.
## `finalizeWithdrawalTransaction` should revert if the finalization period has not elapsed.
**Test:** [`OptimismPortal.t.sol#L171`](../test/invariants/OptimismPortal.t.sol#L171)
**Test:** [`OptimismPortal.t.sol#L174`](../test/invariants/OptimismPortal.t.sol#L174)
A withdrawal that has been proven should not be able to be finalized until after the finalization period has elapsed.
## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized.
**Test:** [`OptimismPortal.t.sol#L201`](../test/invariants/OptimismPortal.t.sol#L201)
**Test:** [`OptimismPortal.t.sol#L204`](../test/invariants/OptimismPortal.t.sol#L204)
Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice.
## A withdrawal should **always** be able to be finalized `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.
**Test:** [`OptimismPortal.t.sol#L230`](../test/invariants/OptimismPortal.t.sol#L230)
**Test:** [`OptimismPortal.t.sol#L233`](../test/invariants/OptimismPortal.t.sol#L233)
This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.
\ No newline at end of file
This diff is collapsed.
......@@ -3,28 +3,28 @@ pragma solidity 0.8.15;
// Testing utilities
import { Test } from "forge-std/Test.sol";
import { Messenger_Initializer, Test } from "test/CommonTest.t.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
import { Reverter, CallerCaller } from "test/mocks/Callers.sol";
import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { CallerCaller, Reverter } from "test/mocks/Callers.sol";
// Libraries
import { Predeploys } from "src/libraries/Predeploys.sol";
import { Hashing } from "src/libraries/Hashing.sol";
import { Encoding } from "src/libraries/Encoding.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
// CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2
// CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract.
contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {
contract CrossDomainMessenger_BaseGas_Test is Bridge_Initializer {
/// @dev Ensure that baseGas passes for the max value of _minGasLimit,
/// this is about 4 Billion.
function test_baseGas_succeeds() external view {
L1Messenger.baseGas(hex"ff", type(uint32).max);
l1CrossDomainMessenger.baseGas(hex"ff", type(uint32).max);
}
/// @dev Fuzz for other values which might cause a revert in baseGas.
function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view {
L1Messenger.baseGas(hex"ff", _minGasLimit);
l1CrossDomainMessenger.baseGas(hex"ff", _minGasLimit);
}
/// @notice The baseGas function should always return a value greater than
......@@ -33,8 +33,8 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {
/// gas to the OptimismPortal.
function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit) external {
vm.assume(_data.length <= type(uint64).max);
uint64 baseGas = L1Messenger.baseGas(_data, _minGasLimit);
uint64 minGasLimit = op.minimumGasLimit(uint64(_data.length));
uint64 baseGas = l1CrossDomainMessenger.baseGas(_data, _minGasLimit);
uint64 minGasLimit = optimismPortal.minimumGasLimit(uint64(_data.length));
assertTrue(baseGas >= minGasLimit);
}
}
......@@ -45,18 +45,18 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {
contract ExternalRelay is Test {
address internal op;
address internal fuzzedSender;
L1CrossDomainMessenger internal L1Messenger;
L1CrossDomainMessenger internal l1CrossDomainMessenger;
event FailedRelayedMessage(bytes32 indexed msgHash);
constructor(L1CrossDomainMessenger _l1Messenger, address _op) {
L1Messenger = _l1Messenger;
l1CrossDomainMessenger = _l1Messenger;
op = _op;
}
/// @notice Internal helper function to relay a message and perform assertions.
function _internalRelay(address _innerSender) internal {
address initialSender = L1Messenger.xDomainMessageSender();
address initialSender = l1CrossDomainMessenger.xDomainMessageSender();
bytes memory callMessage = getCallData();
......@@ -73,7 +73,7 @@ contract ExternalRelay is Test {
emit FailedRelayedMessage(hash);
vm.prank(address(op));
L1Messenger.relayMessage({
l1CrossDomainMessenger.relayMessage({
_nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),
_sender: _innerSender,
_target: address(this),
......@@ -82,9 +82,9 @@ contract ExternalRelay is Test {
_message: callMessage
});
assertTrue(L1Messenger.failedMessages(hash));
assertFalse(L1Messenger.successfulMessages(hash));
assertEq(initialSender, L1Messenger.xDomainMessageSender());
assertTrue(l1CrossDomainMessenger.failedMessages(hash));
assertFalse(l1CrossDomainMessenger.successfulMessages(hash));
assertEq(initialSender, l1CrossDomainMessenger.xDomainMessageSender());
}
/// @notice externalCallWithMinGas is called by the CrossDomainMessenger.
......@@ -111,7 +111,7 @@ contract ExternalRelay is Test {
/// @title CrossDomainMessenger_RelayMessage_Test
/// @notice Fuzz tests re-entrancy into the CrossDomainMessenger relayMessage function.
contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer {
contract CrossDomainMessenger_RelayMessage_Test is Bridge_Initializer {
// Storage slot of the l2Sender
uint256 constant senderSlotIndex = 50;
......@@ -119,7 +119,7 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer {
function setUp() public override {
super.setUp();
er = new ExternalRelay(L1Messenger, address(op));
er = new ExternalRelay(l1CrossDomainMessenger, address(optimismPortal));
}
/// @dev This test mocks an OptimismPortal call to the L1CrossDomainMessenger via
......@@ -151,9 +151,9 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer {
});
// set the value of op.l2Sender() to be the L2 Cross Domain Messenger.
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
vm.prank(address(op));
L1Messenger.relayMessage({
vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
vm.prank(address(optimismPortal));
l1CrossDomainMessenger.relayMessage({
_nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),
_sender: sender,
_target: target,
......@@ -162,11 +162,11 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer {
_message: callMessage
});
assertTrue(L1Messenger.successfulMessages(hash));
assertEq(L1Messenger.failedMessages(hash), false);
assertTrue(l1CrossDomainMessenger.successfulMessages(hash));
assertEq(l1CrossDomainMessenger.failedMessages(hash), false);
// Ensures that the `xDomainMsgSender` is set back to `Predeploys.L2_CROSS_DOMAIN_MESSENGER`
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L1Messenger.xDomainMessageSender();
l1CrossDomainMessenger.xDomainMessageSender();
}
}
......@@ -4,7 +4,7 @@ pragma solidity 0.8.15;
// Testing utilities
import { VmSafe } from "forge-std/Vm.sol";
import { Test } from "forge-std/Test.sol";
import { Portal_Initializer } from "test/CommonTest.t.sol";
import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries
import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";
......@@ -46,7 +46,7 @@ contract CrossDomainOwnable_Test is Test {
}
}
contract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {
contract CrossDomainOwnableThroughPortal_Test is CommonTest {
XDomainSetter setter;
/// @dev Sets up the test suite.
......@@ -63,7 +63,7 @@ contract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {
vm.recordLogs();
vm.prank(alice);
op.depositTransaction({
optimismPortal.depositTransaction({
_to: address(setter),
_value: 0,
_gasLimit: 30_000,
......
......@@ -2,7 +2,7 @@
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest, Messenger_Initializer } from "test/CommonTest.t.sol";
import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
// Libraries
import { Hashing } from "src/libraries/Hashing.sol";
......@@ -10,10 +10,10 @@ import { Encoding } from "src/libraries/Encoding.sol";
import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";
// Target contract dependencies
import { AddressAliasHelper } from "../src/vendor/AddressAliasHelper.sol";
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
// Target contract
import { CrossDomainOwnable2 } from "../src/L2/CrossDomainOwnable2.sol";
import { CrossDomainOwnable2 } from "src/L2/CrossDomainOwnable2.sol";
contract XDomainSetter2 is CrossDomainOwnable2 {
uint256 public value;
......@@ -23,7 +23,7 @@ contract XDomainSetter2 is CrossDomainOwnable2 {
}
}
contract CrossDomainOwnable2_Test is Messenger_Initializer {
contract CrossDomainOwnable2_Test is Bridge_Initializer {
XDomainSetter2 setter;
/// @dev Sets up the test suite.
......@@ -44,9 +44,9 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
// set the xDomainMsgSender storage slot
bytes32 key = bytes32(uint256(204));
bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice));
vm.store(address(L2Messenger), key, value);
vm.store(address(l2CrossDomainMessenger), key, value);
vm.prank(address(L2Messenger));
vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("CrossDomainOwnable2: caller is not the owner");
setter.set(1);
}
......@@ -69,8 +69,10 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
vm.expectEmit(true, true, true, true);
emit FailedRelayedMessage(hash);
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));
L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message);
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)));
l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message
);
assertEq(setter.value(), 0);
}
......@@ -81,8 +83,8 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
// Simulate the L2 execution where the call is coming from
// the L1CrossDomainMessenger
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));
L2Messenger.relayMessage(
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)));
l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce(1, 1),
owner,
address(setter),
......
......@@ -2,7 +2,7 @@
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest, Messenger_Initializer } from "test/CommonTest.t.sol";
import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
// Libraries
import { Hashing } from "src/libraries/Hashing.sol";
......@@ -23,7 +23,7 @@ contract XDomainSetter3 is CrossDomainOwnable3 {
}
}
contract CrossDomainOwnable3_Test is Messenger_Initializer {
contract CrossDomainOwnable3_Test is Bridge_Initializer {
XDomainSetter3 setter;
/// @dev CrossDomainOwnable3.sol transferOwnership event
......@@ -73,9 +73,9 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
// set the xDomainMsgSender storage slot
bytes32 key = bytes32(uint256(204));
bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob);
vm.store(address(L2Messenger), key, value);
vm.store(address(l2CrossDomainMessenger), key, value);
vm.prank(address(L2Messenger));
vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("CrossDomainOwnable3: caller is not the owner");
setter.set(1);
}
......@@ -109,11 +109,13 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
// It should be a failed message. The revert is caught,
// so we cannot expectRevert here.
vm.expectEmit(true, true, true, true, address(L2Messenger));
vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger));
emit FailedRelayedMessage(hash);
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));
L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message);
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)));
l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message
);
assertEq(setter.value(), 0);
}
......@@ -212,8 +214,8 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
// Simulate the L2 execution where the call is coming from
// the L1CrossDomainMessenger
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));
L2Messenger.relayMessage(
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)));
l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce(1, 1),
bob,
address(setter),
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { CommonTest } from "test/CommonTest.t.sol";
import { CommonTest } from "test/setup/CommonTest.sol";
import { DelayedVetoable } from "src/L1/DelayedVetoable.sol";
contract DelayedVetoable_Init is CommonTest {
......@@ -146,7 +146,7 @@ contract DelayedVetoable_HandleCall_TestFail is DelayedVetoable_Init {
/// @dev Only the initiator can initiate a call.
function test_handleCall_unauthorizedInitiation_reverts() external {
vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, initiator, address(this)));
(bool success,) = address(delayedVetoable).call(NON_ZERO_DATA);
(bool success,) = address(delayedVetoable).call(hex"00001234");
assertTrue(success);
}
......
......@@ -8,9 +8,9 @@ import { Test } from "forge-std/Test.sol";
import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol";
import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { Proxy } from "src/universal/Proxy.sol";
import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol";
import { CommonTest } from "test/setup/CommonTest.sol";
contract DisputeGameFactory_Init is L2OutputOracle_Initializer {
contract DisputeGameFactory_Init is CommonTest {
DisputeGameFactory factory;
FakeClone fakeClone;
......
......@@ -2,7 +2,7 @@
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "test/CommonTest.t.sol";
import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries
import { Types } from "src/libraries/Types.sol";
......
......@@ -37,9 +37,9 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
vm.warp(1690906994);
// Propose 2 mock outputs
vm.startPrank(oracle.PROPOSER());
vm.startPrank(l2OutputOracle.PROPOSER());
for (uint256 i; i < 2; i++) {
oracle.proposeL2Output(bytes32(i + 1), oracle.nextBlockNumber(), blockhash(i), i);
l2OutputOracle.proposeL2Output(bytes32(i + 1), l2OutputOracle.nextBlockNumber(), blockhash(i), i);
// Advance 1 block
vm.roll(block.number + 1);
......@@ -52,7 +52,7 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
blockOracle.checkpoint();
// Set the extra data for the game creation
extraData = abi.encode(oracle.SUBMISSION_INTERVAL() * 2, block.number - 1);
extraData = abi.encode(l2OutputOracle.SUBMISSION_INTERVAL() * 2, block.number - 1);
// Deploy an implementation of the fault game
gameImpl = new FaultDisputeGame(
......@@ -61,7 +61,7 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
4,
Duration.wrap(7 days),
new AlphabetVM(absolutePrestate),
oracle,
l2OutputOracle,
blockOracle
);
// Register the game implementation with the factory.
......@@ -127,7 +127,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
function test_initialize_l1HeadTooOld_reverts() public {
// Store a mock block hash for the genesis block. The timestamp will default to 0.
vm.store(address(gameImpl.BLOCK_ORACLE()), keccak256(abi.encode(0, 0)), bytes32(uint256(1)));
bytes memory _extraData = abi.encode(oracle.SUBMISSION_INTERVAL() * 2, 0);
bytes memory _extraData = abi.encode(l2OutputOracle.SUBMISSION_INTERVAL() * 2, 0);
vm.expectRevert(L1HeadTooOld.selector);
factory.create(GAME_TYPE, ROOT_CLAIM, _extraData);
......@@ -139,7 +139,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// For now, it is critical that the first proposed output root of an OP stack
/// chain is done so by an honest party.
function test_initialize_firstOutput_reverts() public {
uint256 submissionInterval = oracle.SUBMISSION_INTERVAL();
uint256 submissionInterval = l2OutputOracle.submissionInterval();
vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x11));
factory.create(GAME_TYPE, ROOT_CLAIM, abi.encode(submissionInterval, block.number - 1));
}
......@@ -160,12 +160,12 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
// Starting
(FaultDisputeGame.OutputProposal memory startingProp, FaultDisputeGame.OutputProposal memory disputedProp) =
gameProxy.proposals();
Types.OutputProposal memory starting = oracle.getL2Output(startingProp.index);
Types.OutputProposal memory starting = l2OutputOracle.getL2Output(startingProp.index);
assertEq(startingProp.index, 0);
assertEq(startingProp.l2BlockNumber, starting.l2BlockNumber);
assertEq(Hash.unwrap(startingProp.outputRoot), starting.outputRoot);
// Disputed
Types.OutputProposal memory disputed = oracle.getL2Output(disputedProp.index);
Types.OutputProposal memory disputed = l2OutputOracle.getL2Output(disputedProp.index);
assertEq(disputedProp.index, 1);
assertEq(disputedProp.l2BlockNumber, disputed.l2BlockNumber);
assertEq(Hash.unwrap(disputedProp.outputRoot), disputed.outputRoot);
......
......@@ -2,49 +2,24 @@
pragma solidity 0.8.15;
// Testing utilities
import { Bridge_Initializer } from "test/CommonTest.t.sol";
import { BaseFeeVault } from "src/L2/BaseFeeVault.sol";
import { StandardBridge } from "src/universal/StandardBridge.sol";
// Libraries
import { Predeploys } from "src/libraries/Predeploys.sol";
// Target contract dependencies
import { FeeVault } from "src/universal/FeeVault.sol";
import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
// Target contract
import { L1FeeVault } from "src/L2/L1FeeVault.sol";
import { FeeVault } from "src/universal/FeeVault.sol";
// Test the implementations of the FeeVault
contract FeeVault_Test is Bridge_Initializer {
BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT));
L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT));
uint256 constant otherMinimumWithdrawalAmount = 10 ether;
/// @dev Sets up the test suite.
function setUp() public override {
super.setUp();
vm.etch(
Predeploys.BASE_FEE_VAULT,
address(new BaseFeeVault(alice, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L1)).code
);
vm.etch(
Predeploys.L1_FEE_VAULT,
address(new L1FeeVault(bob, otherMinimumWithdrawalAmount, FeeVault.WithdrawalNetwork.L2)).code
);
vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault");
vm.label(Predeploys.L1_FEE_VAULT, "L1FeeVault");
/// @dev Tests that the constructor sets the correct values.
function test_constructor_l1FeeVault_succeeds() external {
assertEq(l1FeeVault.RECIPIENT(), cfg.l1FeeVaultRecipient());
assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), cfg.l1FeeVaultMinimumWithdrawalAmount());
assertEq(uint8(l1FeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L2));
}
/// @dev Tests that the constructor sets the correct values.
function test_constructor_succeeds() external {
assertEq(baseFeeVault.RECIPIENT(), alice);
assertEq(l1FeeVault.RECIPIENT(), bob);
assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), NON_ZERO_VALUE);
assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), otherMinimumWithdrawalAmount);
function test_constructor_baseFeeVault_succeeds() external {
assertEq(baseFeeVault.RECIPIENT(), cfg.baseFeeVaultRecipient());
assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), cfg.baseFeeVaultMinimumWithdrawalAmount());
assertEq(uint8(baseFeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L1));
assertEq(uint8(l1FeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L2));
}
}
......@@ -2,22 +2,13 @@
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "test/CommonTest.t.sol";
// Target contract dependencies
import { L1Block } from "src/L2/L1Block.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
// Target contract
import { GasPriceOracle } from "src/L2/GasPriceOracle.sol";
import { CommonTest } from "test/setup/CommonTest.sol";
contract GasPriceOracle_Test is CommonTest {
event OverheadUpdated(uint256);
event ScalarUpdated(uint256);
event DecimalsUpdated(uint256);
GasPriceOracle gasOracle;
L1Block l1Block;
address depositor;
// The initial L1 context values
......@@ -33,17 +24,9 @@ contract GasPriceOracle_Test is CommonTest {
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
// place the L1Block contract at the predeploy address
vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);
l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);
depositor = l1Block.DEPOSITOR_ACCOUNT();
// We are not setting the gas oracle at its predeploy
// address for simplicity purposes. Nothing in this test
// requires it to be at a particular address
gasOracle = new GasPriceOracle();
vm.prank(depositor);
l1Block.setL1BlockValues({
_number: number,
......@@ -59,43 +42,43 @@ contract GasPriceOracle_Test is CommonTest {
/// @dev Tests that `l1BaseFee` is set correctly.
function test_l1BaseFee_succeeds() external {
assertEq(gasOracle.l1BaseFee(), basefee);
assertEq(gasPriceOracle.l1BaseFee(), basefee);
}
/// @dev Tests that `gasPrice` is set correctly.
function test_gasPrice_succeeds() external {
vm.fee(100);
uint256 gasPrice = gasOracle.gasPrice();
uint256 gasPrice = gasPriceOracle.gasPrice();
assertEq(gasPrice, 100);
}
/// @dev Tests that `baseFee` is set correctly.
function test_baseFee_succeeds() external {
vm.fee(64);
uint256 gasPrice = gasOracle.baseFee();
uint256 gasPrice = gasPriceOracle.baseFee();
assertEq(gasPrice, 64);
}
/// @dev Tests that `scalar` is set correctly.
function test_scalar_succeeds() external {
assertEq(gasOracle.scalar(), l1FeeScalar);
assertEq(gasPriceOracle.scalar(), l1FeeScalar);
}
/// @dev Tests that `overhead` is set correctly.
function test_overhead_succeeds() external {
assertEq(gasOracle.overhead(), l1FeeOverhead);
assertEq(gasPriceOracle.overhead(), l1FeeOverhead);
}
/// @dev Tests that `decimals` is set correctly.
function test_decimals_succeeds() external {
assertEq(gasOracle.decimals(), 6);
assertEq(gasOracle.DECIMALS(), 6);
assertEq(gasPriceOracle.decimals(), 6);
assertEq(gasPriceOracle.DECIMALS(), 6);
}
/// @dev Tests that `setGasPrice` reverts since it was removed in bedrock.
function test_setGasPrice_doesNotExist_reverts() external {
(bool success, bytes memory returndata) =
address(gasOracle).call(abi.encodeWithSignature("setGasPrice(uint256)", 1));
address(gasPriceOracle).call(abi.encodeWithSignature("setGasPrice(uint256)", 1));
assertEq(success, false);
assertEq(returndata, hex"");
......@@ -104,7 +87,7 @@ contract GasPriceOracle_Test is CommonTest {
/// @dev Tests that `setL1BaseFee` reverts since it was removed in bedrock.
function test_setL1BaseFee_doesNotExist_reverts() external {
(bool success, bytes memory returndata) =
address(gasOracle).call(abi.encodeWithSignature("setL1BaseFee(uint256)", 1));
address(gasPriceOracle).call(abi.encodeWithSignature("setL1BaseFee(uint256)", 1));
assertEq(success, false);
assertEq(returndata, hex"");
......
......@@ -2,41 +2,37 @@
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "test/CommonTest.t.sol";
// Target contract
import { GovernanceToken } from "src/governance/GovernanceToken.sol";
import { CommonTest } from "test/setup/CommonTest.sol";
contract GovernanceToken_Test is CommonTest {
address constant owner = address(0x1234);
address constant rando = address(0x5678);
GovernanceToken internal gov;
address owner;
address rando;
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
vm.prank(owner);
gov = new GovernanceToken();
owner = governanceToken.owner();
rando = makeAddr("rando");
}
/// @dev Tests that the constructor sets the correct initial state.
function test_constructor_succeeds() external {
assertEq(gov.owner(), owner);
assertEq(gov.name(), "Optimism");
assertEq(gov.symbol(), "OP");
assertEq(gov.decimals(), 18);
assertEq(gov.totalSupply(), 0);
assertEq(governanceToken.owner(), owner);
assertEq(governanceToken.name(), "Optimism");
assertEq(governanceToken.symbol(), "OP");
assertEq(governanceToken.decimals(), 18);
assertEq(governanceToken.totalSupply(), 0);
}
/// @dev Tests that the owner can successfully call `mint`.
function test_mint_fromOwner_succeeds() external {
// Mint 100 tokens.
vm.prank(owner);
gov.mint(owner, 100);
governanceToken.mint(owner, 100);
// Balances have updated correctly.
assertEq(gov.balanceOf(owner), 100);
assertEq(gov.totalSupply(), 100);
assertEq(governanceToken.balanceOf(owner), 100);
assertEq(governanceToken.totalSupply(), 100);
}
/// @dev Tests that `mint` reverts when called by a non-owner.
......@@ -44,130 +40,130 @@ contract GovernanceToken_Test is CommonTest {
// Mint 100 tokens as rando.
vm.prank(rando);
vm.expectRevert("Ownable: caller is not the owner");
gov.mint(owner, 100);
governanceToken.mint(owner, 100);
// Balance does not update.
assertEq(gov.balanceOf(owner), 0);
assertEq(gov.totalSupply(), 0);
assertEq(governanceToken.balanceOf(owner), 0);
assertEq(governanceToken.totalSupply(), 0);
}
/// @dev Tests that the owner can successfully call `burn`.
function test_burn_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
gov.mint(rando, 100);
governanceToken.mint(rando, 100);
// Rando burns their tokens.
vm.prank(rando);
gov.burn(50);
governanceToken.burn(50);
// Balances have updated correctly.
assertEq(gov.balanceOf(rando), 50);
assertEq(gov.totalSupply(), 50);
assertEq(governanceToken.balanceOf(rando), 50);
assertEq(governanceToken.totalSupply(), 50);
}
/// @dev Tests that the owner can successfully call `burnFrom`.
function test_burnFrom_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
gov.mint(rando, 100);
governanceToken.mint(rando, 100);
// Rando approves owner to burn 50 tokens.
vm.prank(rando);
gov.approve(owner, 50);
governanceToken.approve(owner, 50);
// Owner burns 50 tokens from rando.
vm.prank(owner);
gov.burnFrom(rando, 50);
governanceToken.burnFrom(rando, 50);
// Balances have updated correctly.
assertEq(gov.balanceOf(rando), 50);
assertEq(gov.totalSupply(), 50);
assertEq(governanceToken.balanceOf(rando), 50);
assertEq(governanceToken.totalSupply(), 50);
}
/// @dev Tests that `transfer` correctly transfers tokens.
function test_transfer_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
gov.mint(rando, 100);
governanceToken.mint(rando, 100);
// Rando transfers 50 tokens to owner.
vm.prank(rando);
gov.transfer(owner, 50);
governanceToken.transfer(owner, 50);
// Balances have updated correctly.
assertEq(gov.balanceOf(owner), 50);
assertEq(gov.balanceOf(rando), 50);
assertEq(gov.totalSupply(), 100);
assertEq(governanceToken.balanceOf(owner), 50);
assertEq(governanceToken.balanceOf(rando), 50);
assertEq(governanceToken.totalSupply(), 100);
}
/// @dev Tests that `approve` correctly sets allowances.
function test_approve_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
gov.mint(rando, 100);
governanceToken.mint(rando, 100);
// Rando approves owner to spend 50 tokens.
vm.prank(rando);
gov.approve(owner, 50);
governanceToken.approve(owner, 50);
// Allowances have updated.
assertEq(gov.allowance(rando, owner), 50);
assertEq(governanceToken.allowance(rando, owner), 50);
}
/// @dev Tests that `transferFrom` correctly transfers tokens.
function test_transferFrom_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
gov.mint(rando, 100);
governanceToken.mint(rando, 100);
// Rando approves owner to spend 50 tokens.
vm.prank(rando);
gov.approve(owner, 50);
governanceToken.approve(owner, 50);
// Owner transfers 50 tokens from rando to owner.
vm.prank(owner);
gov.transferFrom(rando, owner, 50);
governanceToken.transferFrom(rando, owner, 50);
// Balances have updated correctly.
assertEq(gov.balanceOf(owner), 50);
assertEq(gov.balanceOf(rando), 50);
assertEq(gov.totalSupply(), 100);
assertEq(governanceToken.balanceOf(owner), 50);
assertEq(governanceToken.balanceOf(rando), 50);
assertEq(governanceToken.totalSupply(), 100);
}
/// @dev Tests that `increaseAllowance` correctly increases allowances.
function test_increaseAllowance_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
gov.mint(rando, 100);
governanceToken.mint(rando, 100);
// Rando approves owner to spend 50 tokens.
vm.prank(rando);
gov.approve(owner, 50);
governanceToken.approve(owner, 50);
// Rando increases allowance by 50 tokens.
vm.prank(rando);
gov.increaseAllowance(owner, 50);
governanceToken.increaseAllowance(owner, 50);
// Allowances have updated.
assertEq(gov.allowance(rando, owner), 100);
assertEq(governanceToken.allowance(rando, owner), 100);
}
/// @dev Tests that `decreaseAllowance` correctly decreases allowances.
function test_decreaseAllowance_succeeds() external {
// Mint 100 tokens to rando.
vm.prank(owner);
gov.mint(rando, 100);
governanceToken.mint(rando, 100);
// Rando approves owner to spend 100 tokens.
vm.prank(rando);
gov.approve(owner, 100);
governanceToken.approve(owner, 100);
// Rando decreases allowance by 50 tokens.
vm.prank(rando);
gov.decreaseAllowance(owner, 50);
governanceToken.decreaseAllowance(owner, 50);
// Allowances have updated.
assertEq(gov.allowance(rando, owner), 50);
assertEq(governanceToken.allowance(rando, owner), 50);
}
}
......@@ -2,7 +2,7 @@
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "test/CommonTest.t.sol";
import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries
import { Types } from "src/libraries/Types.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol";
import { console } from "forge-std/console.sol";
import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol";
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { SystemConfig } from "src/L1/SystemConfig.sol";
......@@ -13,19 +12,19 @@ import { OptimismPortal } from "src/L1/OptimismPortal.sol";
/// @dev Ensures that the `initialize()` function on contracts cannot be called more than
/// once. This contract inherits from `ERC721Bridge_Initializer` because it is the
/// deepest contract in the inheritance chain for setting up the system contracts.
contract Initializer_Test is ERC721Bridge_Initializer {
contract Initializer_Test is Bridge_Initializer {
function test_cannotReinitializeL1_succeeds() public {
vm.expectRevert("Initializable: contract is already initialized");
L1Messenger.initialize(OptimismPortal(payable(address(0))));
l1CrossDomainMessenger.initialize(OptimismPortal(payable(address(0))));
vm.expectRevert("Initializable: contract is already initialized");
L1Bridge.initialize(CrossDomainMessenger(address(0)));
l1StandardBridge.initialize(CrossDomainMessenger(address(0)));
vm.expectRevert("Initializable: contract is already initialized");
oracle.initialize(0, 0, address(0), address(0));
l2OutputOracle.initialize(0, 0, address(0), address(0));
vm.expectRevert("Initializable: contract is already initialized");
op.initialize(L2OutputOracle(address(0)), address(0), SystemConfig(address(0)), false);
optimismPortal.initialize(L2OutputOracle(address(0)), address(0), SystemConfig(address(0)), false);
vm.expectRevert("Initializable: contract is already initialized");
systemConfig.initialize({
......@@ -56,6 +55,6 @@ contract Initializer_Test is ERC721Bridge_Initializer {
});
vm.expectRevert("Initializable: contract is already initialized");
L1NFTBridge.initialize(CrossDomainMessenger(address(0)));
l1ERC721Bridge.initialize(CrossDomainMessenger(address(0)));
}
}
......@@ -2,27 +2,25 @@
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "test/CommonTest.t.sol";
import { CommonTest } from "test/setup/CommonTest.sol";
// Target contract
import { L1Block } from "src/L2/L1Block.sol";
contract L1BlockTest is CommonTest {
L1Block lb;
address depositor;
bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1));
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
lb = new L1Block();
depositor = lb.DEPOSITOR_ACCOUNT();
depositor = l1Block.DEPOSITOR_ACCOUNT();
vm.prank(depositor);
lb.setL1BlockValues({
l1Block.setL1BlockValues({
_number: uint64(1),
_timestamp: uint64(2),
_basefee: 3,
_hash: NON_ZERO_HASH,
_hash: keccak256(abi.encode(block.number)),
_sequenceNumber: uint64(4),
_batcherHash: bytes32(0),
_l1FeeOverhead: 2,
......@@ -44,46 +42,46 @@ contract L1BlockTest is CommonTest {
external
{
vm.prank(depositor);
lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs);
assertEq(lb.number(), n);
assertEq(lb.timestamp(), t);
assertEq(lb.basefee(), b);
assertEq(lb.hash(), h);
assertEq(lb.sequenceNumber(), s);
assertEq(lb.batcherHash(), bt);
assertEq(lb.l1FeeOverhead(), fo);
assertEq(lb.l1FeeScalar(), fs);
l1Block.setL1BlockValues(n, t, b, h, s, bt, fo, fs);
assertEq(l1Block.number(), n);
assertEq(l1Block.timestamp(), t);
assertEq(l1Block.basefee(), b);
assertEq(l1Block.hash(), h);
assertEq(l1Block.sequenceNumber(), s);
assertEq(l1Block.batcherHash(), bt);
assertEq(l1Block.l1FeeOverhead(), fo);
assertEq(l1Block.l1FeeScalar(), fs);
}
/// @dev Tests that `number` returns the correct value.
function test_number_succeeds() external {
assertEq(lb.number(), uint64(1));
assertEq(l1Block.number(), uint64(1));
}
/// @dev Tests that `timestamp` returns the correct value.
function test_timestamp_succeeds() external {
assertEq(lb.timestamp(), uint64(2));
assertEq(l1Block.timestamp(), uint64(2));
}
/// @dev Tests that `basefee` returns the correct value.
function test_basefee_succeeds() external {
assertEq(lb.basefee(), 3);
assertEq(l1Block.basefee(), 3);
}
/// @dev Tests that `hash` returns the correct value.
function test_hash_succeeds() external {
assertEq(lb.hash(), NON_ZERO_HASH);
assertEq(l1Block.hash(), keccak256(abi.encode(block.number)));
}
/// @dev Tests that `sequenceNumber` returns the correct value.
function test_sequenceNumber_succeeds() external {
assertEq(lb.sequenceNumber(), uint64(4));
assertEq(l1Block.sequenceNumber(), uint64(4));
}
/// @dev Tests that `setL1BlockValues` can set max values.
function test_updateValues_succeeds() external {
vm.prank(depositor);
lb.setL1BlockValues({
l1Block.setL1BlockValues({
_number: type(uint64).max,
_timestamp: type(uint64).max,
_basefee: type(uint256).max,
......
......@@ -2,7 +2,7 @@
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "test/CommonTest.t.sol";
import { CommonTest } from "test/setup/CommonTest.sol";
// Target contract dependencies
import { Predeploys } from "src/libraries/Predeploys.sol";
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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