github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity 0.8.15;
     3  
     4  import { CommonTest } from "test/setup/CommonTest.sol";
     5  import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
     6  import { Vm } from "forge-std/Vm.sol";
     7  
     8  contract L2OutputOracle_Proposer {
     9      L2OutputOracle internal oracle;
    10      Vm internal vm;
    11  
    12      constructor(L2OutputOracle _oracle, Vm _vm) {
    13          oracle = _oracle;
    14          vm = _vm;
    15      }
    16  
    17      /// @dev Allows the actor to propose an L2 output to the `L2OutputOracle`
    18      function proposeL2Output(
    19          bytes32 _outputRoot,
    20          uint256 _l2BlockNumber,
    21          bytes32 _l1BlockHash,
    22          uint256 _l1BlockNumber
    23      )
    24          external
    25      {
    26          // Act as the proposer and propose a new output.
    27          vm.prank(oracle.PROPOSER());
    28          oracle.proposeL2Output(_outputRoot, _l2BlockNumber, _l1BlockHash, _l1BlockNumber);
    29      }
    30  }
    31  
    32  contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is CommonTest {
    33      L2OutputOracle_Proposer internal actor;
    34  
    35      function setUp() public override {
    36          super.setUp();
    37  
    38          // Create a proposer actor.
    39          actor = new L2OutputOracle_Proposer(l2OutputOracle, vm);
    40  
    41          // Set the target contract to the proposer actor.
    42          targetContract(address(actor));
    43  
    44          // Set the target selector for `proposeL2Output`
    45          // `proposeL2Output` is the only function we care about, as it is the only function
    46          // that can modify the `l2Outputs` array in the oracle.
    47          bytes4[] memory selectors = new bytes4[](1);
    48          selectors[0] = actor.proposeL2Output.selector;
    49          FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors });
    50          targetSelector(selector);
    51      }
    52  
    53      /// @custom:invariant The block number of the output root proposals should monotonically
    54      ///                   increase.
    55      ///
    56      ///                   When a new output is submitted, it should never be allowed to
    57      ///                   correspond to a block number that is less than the current output.
    58      function invariant_monotonicBlockNumIncrease() external {
    59          // Assert that the block number of proposals must monotonically increase.
    60          assertTrue(l2OutputOracle.nextBlockNumber() >= l2OutputOracle.latestBlockNumber());
    61      }
    62  }