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 }