Commit 67a9b321 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #7863 from ethereum-optimism/ctb/dead-delete-output

contracts-bedrock: delete dead delete output code
parents 39678401 bd23c0aa
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { LibSort } from "../libraries/LibSort.sol";
import { IGnosisSafe, Enum } from "../interfaces/IGnosisSafe.sol";
import { SafeBuilder } from "../universal/SafeBuilder.sol";
import { Types } from "../../src/libraries/Types.sol";
import { FeeVault } from "../../src/universal/FeeVault.sol";
import { L2OutputOracle } from "../../src/L1/L2OutputOracle.sol";
import { Predeploys } from "../../src/libraries/Predeploys.sol";
/// @title DeleteOutput
/// @notice Deletes an output root from the L2OutputOracle.
/// @notice Example usage is provided in the README documentation.
contract DeleteOutput is SafeBuilder {
/// @notice A set of contract addresses for the script.
struct ContractSet {
address Safe;
address ProxyAdmin;
address L2OutputOracleProxy;
}
/// @notice A mapping of chainid to a ContractSet.
mapping(uint256 => ContractSet) internal _contracts;
/// @notice The l2 output index we will delete.
uint256 internal index;
/// @notice The address of the L2OutputOracle to target.
address internal oracle;
/// @notice Place the contract addresses in storage for ux.
function setUp() external {
_contracts[GOERLI] = ContractSet({
Safe: 0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f,
ProxyAdmin: 0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d,
L2OutputOracleProxy: 0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0
});
}
/// @notice Returns the ContractSet for the defined block chainid.
/// @dev Reverts if no ContractSet is defined.
function contracts() public view returns (ContractSet memory) {
ContractSet memory cs = _contracts[block.chainid];
if (cs.Safe == address(0) || cs.ProxyAdmin == address(0) || cs.L2OutputOracleProxy == address(0)) {
revert("Missing Contract Set for the given block.chainid");
}
return cs;
}
/// @notice Executes the gnosis safe transaction to delete an L2 Output Root.
function run(uint256 _index) external returns (bool) {
address _safe = contracts().Safe;
address _proxyAdmin = contracts().ProxyAdmin;
index = _index;
return run(_safe, _proxyAdmin);
}
/// @notice Follow up assertions to ensure that the script ran to completion.
function _postCheck() internal view override {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
Types.OutputProposal memory proposal = l2oo.getL2Output(index);
require(proposal.l2BlockNumber == 0, "DeleteOutput: Output deletion failed.");
}
/// @notice Test coverage of the script.
function test_script_succeeds() external skipWhenNotForking {
uint256 _index = getLatestIndex();
require(_index != 0, "DeleteOutput: No outputs to delete.");
index = _index;
address safe = contracts().Safe;
require(safe != address(0), "DeleteOutput: Invalid safe address.");
address proxyAdmin = contracts().ProxyAdmin;
require(proxyAdmin != address(0), "DeleteOutput: Invalid proxy admin address.");
address[] memory owners = IGnosisSafe(payable(safe)).getOwners();
for (uint256 i; i < owners.length; i++) {
address owner = owners[i];
vm.startBroadcast(owner);
bool success = _run(safe, proxyAdmin);
vm.stopBroadcast();
if (success) {
console.log("tx success");
break;
}
}
_postCheck();
}
function buildCalldata(address) internal view override returns (bytes memory) {
IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](1);
calls[0] = IMulticall3.Call3({
target: oracle,
allowFailure: false,
callData: abi.encodeCall(L2OutputOracle.deleteL2Outputs, (index))
});
return abi.encodeCall(IMulticall3.aggregate3, (calls));
}
/// @notice Computes the safe transaction hash.
function computeSafeTransactionHash(uint256 _index) public returns (bytes32) {
ContractSet memory cs = contracts();
address _safe = cs.Safe;
address _proxyAdmin = cs.ProxyAdmin;
index = _index;
oracle = cs.L2OutputOracleProxy;
return _getTransactionHash(_safe, _proxyAdmin);
}
/// @notice Returns the challenger for the L2OutputOracle.
function getChallenger() public view returns (address) {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
return l2oo.CHALLENGER();
}
/// @notice Returns the L2 Block Number for the given index.
function getL2BlockNumber(uint256 _index) public view returns (uint256) {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
return l2oo.getL2Output(_index).l2BlockNumber;
}
/// @notice Returns the output root for the given index.
function getOutputFromIndex(uint256 _index) public view returns (bytes32) {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
return l2oo.getL2Output(_index).outputRoot;
}
/// @notice Returns the output root with the corresponding to the L2 Block Number.
function getOutputFromL2BlockNumber(uint256 l2BlockNumber) public view returns (bytes32) {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
return l2oo.getL2OutputAfter(l2BlockNumber).outputRoot;
}
/// @notice Returns the latest l2 output index.
function getLatestIndex() public view returns (uint256) {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
return l2oo.latestOutputIndex();
}
}
## L2 Output Oracle Scripts
A collection of scripts to interact with the L2OutputOracle.
### Output Deletion
[DeleteOutput](./DeleteOutput.s.sol) contains a variety of functions that deal
with deleting an output root from the [L2OutputOracle](../../contracts/L1/L2OutputOracle.sol).
To delete an output root, the script can be run as follows, where `<L2_OUTPUT_INDEX>` is
the index of the posted output to delete.
```bash
$ forge script scripts/output/DeleteOutput.s.sol \
--sig "run(uint256)" \
--rpc-url $ETH_RPC_URL \
--broadcast \
--private-key $PRIVATE_KEY \
<L2_OUTPUT_INDEX>
```
To find and confirm the output index, there are a variety of helper functions that
can be run using the script `--sig` flag, passing the function signatures in as arguments.
These are outlined below.
### Retrieving an L2 Block Number
The output's associated L2 block number can be retrieved using the following command, where
`<L2_OUTPUT_INDEX>` is the index of the output in the [L2OutputOracle](../../contracts/L1/L2OutputOracle.sol).
```bash
$ forge script scripts/output/DeleteOutput.s.sol \
--sig "getL2BlockNumber(uint256)" \
--rpc-url $ETH_RPC_URL \
<L2_OUTPUT_INDEX>
```
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