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

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity 0.8.15;
     3  
     4  import { StdUtils } from "forge-std/StdUtils.sol";
     5  import { Test } from "forge-std/Test.sol";
     6  import { Vm } from "forge-std/Vm.sol";
     7  
     8  import { StdInvariant } from "forge-std/StdInvariant.sol";
     9  import { Burn } from "src/libraries/Burn.sol";
    10  import { InvariantTest } from "test/invariants/InvariantTest.sol";
    11  
    12  contract Burn_EthBurner is StdUtils {
    13      Vm internal vm;
    14      bool public failedEthBurn;
    15  
    16      constructor(Vm _vm) {
    17          vm = _vm;
    18      }
    19  
    20      /// @notice Takes an integer amount of eth to burn through the Burn library and
    21      ///         updates the contract state if an incorrect amount of eth moved from the contract
    22      function burnEth(uint256 _value) external {
    23          uint256 preBurnvalue = bound(_value, 0, type(uint128).max);
    24  
    25          // Give the burner some ether for gas being used
    26          vm.deal(address(this), preBurnvalue);
    27  
    28          // cache the contract's eth balance
    29          uint256 preBurnBalance = address(this).balance;
    30  
    31          uint256 value = bound(preBurnvalue, 0, preBurnBalance);
    32  
    33          // execute a burn of _value eth
    34          Burn.eth(value);
    35  
    36          // check that exactly value eth was transfered from the contract
    37          unchecked {
    38              if (address(this).balance != preBurnBalance - value) {
    39                  failedEthBurn = true;
    40              }
    41          }
    42      }
    43  }
    44  
    45  contract Burn_BurnEth_Invariant is StdInvariant, InvariantTest {
    46      Burn_EthBurner internal actor;
    47  
    48      function setUp() public override {
    49          super.setUp();
    50          // Create a Eth burner actor.
    51  
    52          actor = new Burn_EthBurner(vm);
    53  
    54          targetContract(address(actor));
    55  
    56          bytes4[] memory selectors = new bytes4[](1);
    57          selectors[0] = actor.burnEth.selector;
    58          FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors });
    59          targetSelector(selector);
    60      }
    61  
    62      /// @custom:invariant `eth(uint256)` always burns the exact amount of eth passed.
    63      ///
    64      ///                   Asserts that when `Burn.eth(uint256)` is called, it always
    65      ///                   burns the exact amount of ETH passed to the function.
    66      function invariant_burn_eth() external {
    67          // ASSERTION: The amount burned should always match the amount passed exactly
    68          assertEq(actor.failedEthBurn(), false);
    69      }
    70  }