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

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity 0.8.15;
     3  
     4  import { Test } from "forge-std/Test.sol";
     5  import { StdInvariant } from "forge-std/StdInvariant.sol";
     6  import { Encoding } from "src/libraries/Encoding.sol";
     7  import { InvariantTest } from "test/invariants/InvariantTest.sol";
     8  
     9  contract Encoding_Converter {
    10      bool public failedRoundtripAToB;
    11      bool public failedRoundtripBToA;
    12  
    13      /// @notice Takes a pair of integers to be encoded into a versioned nonce with the
    14      ///         Encoding library and then decoded and updates the test contract's state
    15      ///         indicating if the round trip encoding failed.
    16      function convertRoundTripAToB(uint240 _nonce, uint16 _version) external {
    17          // Encode the nonce and version
    18          uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(_nonce, _version);
    19  
    20          // Decode the nonce and version
    21          uint240 decodedNonce;
    22          uint16 decodedVersion;
    23  
    24          (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(encodedVersionedNonce);
    25  
    26          // If our round trip encoding did not return the original result, set our state.
    27          if ((decodedNonce != _nonce) || (decodedVersion != _version)) {
    28              failedRoundtripAToB = true;
    29          }
    30      }
    31  
    32      /// @notice Takes an integer representing a packed version and nonce and attempts
    33      ///         to decode them using the Encoding library before re-encoding and updates
    34      ///         the test contract's state indicating if the round trip encoding failed.
    35      function convertRoundTripBToA(uint256 _versionedNonce) external {
    36          // Decode the nonce and version
    37          uint240 decodedNonce;
    38          uint16 decodedVersion;
    39  
    40          (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(_versionedNonce);
    41  
    42          // Encode the nonce and version
    43          uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(decodedNonce, decodedVersion);
    44  
    45          // If our round trip encoding did not return the original result, set our state.
    46          if (encodedVersionedNonce != _versionedNonce) {
    47              failedRoundtripBToA = true;
    48          }
    49      }
    50  }
    51  
    52  contract Encoding_Invariant is StdInvariant, InvariantTest {
    53      Encoding_Converter internal actor;
    54  
    55      function setUp() public override {
    56          super.setUp();
    57          // Create a converter actor.
    58          actor = new Encoding_Converter();
    59  
    60          targetContract(address(actor));
    61  
    62          bytes4[] memory selectors = new bytes4[](2);
    63          selectors[0] = actor.convertRoundTripAToB.selector;
    64          selectors[1] = actor.convertRoundTripBToA.selector;
    65          FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors });
    66          targetSelector(selector);
    67      }
    68  
    69      /// @custom:invariant `convertRoundTripAToB` never fails.
    70      ///
    71      ///                   Asserts that a raw versioned nonce can be encoded / decoded
    72      ///                   to reach the same raw value.
    73      function invariant_round_trip_encoding_AToB() external {
    74          // ASSERTION: The round trip encoding done in testRoundTripAToB(...)
    75          assertEq(actor.failedRoundtripAToB(), false);
    76      }
    77  
    78      /// @custom:invariant `convertRoundTripBToA` never fails.
    79      ///
    80      ///                   Asserts that an encoded versioned nonce can always be decoded /
    81      ///                   re-encoded to reach the same encoded value.
    82      function invariant_round_trip_encoding_BToA() external {
    83          // ASSERTION: The round trip encoding done in testRoundTripBToA should never
    84          // fail.
    85          assertEq(actor.failedRoundtripBToA(), false);
    86      }
    87  }