Commit 84773de7 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge pull request #5252 from ethereum-optimism/feat/fee-vault-withdrawal-script

contracts-bedrock: fee vault withdrawal script
parents 4d644da8 a1117e06
......@@ -244,3 +244,8 @@ Test contracts should be named one of the following according to their use:
- `TargetContract_Init` for contracts that perform basic setup to be reused in other test contracts.
- `TargetContract_Function_Test` for contracts containing happy path tests for a given function.
- `TargetContract_Function_TestFail` for contracts containing sad path tests for a given function.
## Withdrawaing From Fee Vaults
See the file `scripts/FeeVaultWithdrawal.s.sol` to withdraw from the L2 fee vaults. It includes
instructions on how to run it. `foundry` is required.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { Script } from "forge-std/Script.sol";
import { Predeploys } from "../contracts/libraries/Predeploys.sol";
import { FeeVault } from "../contracts/universal/FeeVault.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
/**
* @title FeeVaultWithdrawal
* @notice A script to make it very simple to withdraw from the fee vaults.
* The usage is as follows:
* $ forge script scripts/FeeVaultWithdrawal.s.sol \
* --rpc-url $ETH_RPC_URL --broadcast \
* --private-key $PRIVATE_KEY
*/
contract FeeVaultWithdrawal is Script {
IMulticall3 private constant multicall = IMulticall3(MULTICALL3_ADDRESS);
IMulticall3.Call3[] internal calls;
/**
* @notice The entrypoint function. Determines which FeeVaults can be withdrawn from and then
* will send the transaction via Multicall3 to withdraw all FeeVaults.
*/
function run() external {
require(address(multicall).code.length > 0);
address[] memory vaults = new address[](3);
vaults[0] = Predeploys.SEQUENCER_FEE_WALLET;
vaults[1] = Predeploys.BASE_FEE_VAULT;
vaults[2] = Predeploys.L1_FEE_VAULT;
for (uint256 i; i < vaults.length; i++) {
address vault = vaults[i];
bool shouldCall = canWithdrawal(vault);
if (shouldCall) {
calls.push(IMulticall3.Call3({
target: vault,
allowFailure: false,
callData: abi.encodeWithSelector(FeeVault.withdraw.selector)
}));
address recipient = FeeVault(payable(vault)).RECIPIENT();
uint256 balance = vault.balance;
log(balance, recipient, vault);
} else {
string memory logline = string.concat(
vm.toString(vault),
" does not have a large enough balance to withdraw."
);
console.log(logline);
}
}
if (calls.length > 0) {
vm.broadcast();
multicall.aggregate3(calls);
console.log("Success.");
}
}
/**
* @notice Checks whether or not a FeeVault can be withdrawn. The balance of the account must
* be larger than the `MIN_WITHDRAWAL_AMOUNT`.
*/
function canWithdrawal(address _vault) internal view returns (bool) {
uint256 minWithdrawalAmount = FeeVault(payable(_vault)).MIN_WITHDRAWAL_AMOUNT();
uint256 balance = _vault.balance;
return balance >= minWithdrawalAmount;
}
/**
* @notice Logs the information relevant to the user.
*/
function log(uint256 _balance, address _recipient, address _vault) internal view {
string memory logline = string.concat(
"Withdrawing ",
vm.toString(_balance),
" to ",
vm.toString(_recipient),
" from ",
vm.toString(_vault)
);
console.log(logline);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment