github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/scripts/FeeVaultWithdrawal.s.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity 0.8.15;
     3  
     4  import { console } from "forge-std/console.sol";
     5  import { Script } from "forge-std/Script.sol";
     6  import { Predeploys } from "../src/libraries/Predeploys.sol";
     7  import { FeeVault } from "../src/universal/FeeVault.sol";
     8  import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
     9  
    10  /// @title FeeVaultWithdrawal
    11  /// @notice A script to make it very simple to withdraw from the fee vaults.
    12  ///         The usage is as follows:
    13  ///         $ forge script scripts/FeeVaultWithdrawal.s.sol \
    14  ///             --rpc-url $ETH_RPC_URL --broadcast \
    15  ///             --private-key $PRIVATE_KEY
    16  contract FeeVaultWithdrawal is Script {
    17      IMulticall3 private constant multicall = IMulticall3(MULTICALL3_ADDRESS);
    18      IMulticall3.Call3[] internal calls;
    19  
    20      /// @notice The entrypoint function. Determines which FeeVaults can be withdrawn from and then
    21      ///        will send the transaction via Multicall3 to withdraw all FeeVaults.
    22      function run() external {
    23          require(address(multicall).code.length > 0);
    24  
    25          address[] memory vaults = new address[](3);
    26          vaults[0] = Predeploys.SEQUENCER_FEE_WALLET;
    27          vaults[1] = Predeploys.BASE_FEE_VAULT;
    28          vaults[2] = Predeploys.L1_FEE_VAULT;
    29  
    30          for (uint256 i; i < vaults.length; i++) {
    31              address vault = vaults[i];
    32              bool shouldCall = canWithdrawal(vault);
    33              if (shouldCall) {
    34                  calls.push(
    35                      IMulticall3.Call3({
    36                          target: vault,
    37                          allowFailure: false,
    38                          callData: abi.encodeWithSelector(FeeVault.withdraw.selector)
    39                      })
    40                  );
    41  
    42                  address recipient = FeeVault(payable(vault)).RECIPIENT();
    43                  uint256 balance = vault.balance;
    44                  log(balance, recipient, vault);
    45              } else {
    46                  string memory logline =
    47                      string.concat(vm.toString(vault), " does not have a large enough balance to withdraw.");
    48                  console.log(logline);
    49              }
    50          }
    51  
    52          if (calls.length > 0) {
    53              vm.broadcast();
    54              multicall.aggregate3(calls);
    55              console.log("Success.");
    56          }
    57      }
    58  
    59      /// @notice Checks whether or not a FeeVault can be withdrawn. The balance of the account must
    60      ///         be larger than the `MIN_WITHDRAWAL_AMOUNT`.
    61      function canWithdrawal(address _vault) internal view returns (bool) {
    62          uint256 minWithdrawalAmount = FeeVault(payable(_vault)).MIN_WITHDRAWAL_AMOUNT();
    63          uint256 balance = _vault.balance;
    64          return balance >= minWithdrawalAmount;
    65      }
    66  
    67      /// @notice Logs the information relevant to the user.
    68      function log(uint256 _balance, address _recipient, address _vault) internal view {
    69          string memory logline = string.concat(
    70              "Withdrawing ", vm.toString(_balance), " to ", vm.toString(_recipient), " from ", vm.toString(_vault)
    71          );
    72          console.log(logline);
    73      }
    74  }