Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
9a48edbb
Commit
9a48edbb
authored
Apr 27, 2023
by
Andreas Bigger
Committed by
asnared
May 01, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
L2OutputOracle output deletion script
parent
3170d759
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
344 additions
and
81 deletions
+344
-81
IGnosisSafe.sol
...ages/contracts-bedrock/scripts/interfaces/IGnosisSafe.sol
+0
-0
LibSort.sol
packages/contracts-bedrock/scripts/libraries/LibSort.sol
+0
-0
DeleteOutput.s.sol
...ages/contracts-bedrock/scripts/outputs/DeleteOutput.s.sol
+188
-0
README.md
packages/contracts-bedrock/scripts/outputs/README.md
+38
-0
EnhancedScript.sol
...es/contracts-bedrock/scripts/universal/EnhancedScript.sol
+54
-0
GlobalConstants.sol
...s/contracts-bedrock/scripts/universal/GlobalConstants.sol
+23
-0
SafeBuilder.sol
packages/contracts-bedrock/scripts/universal/SafeBuilder.sol
+36
-76
PostSherlock.s.sol
...ges/contracts-bedrock/scripts/upgrades/PostSherlock.s.sol
+3
-3
PostSherlockL2.s.sol
...s/contracts-bedrock/scripts/upgrades/PostSherlockL2.s.sol
+2
-2
No files found.
packages/contracts-bedrock/scripts/
upgrad
es/IGnosisSafe.sol
→
packages/contracts-bedrock/scripts/
interfac
es/IGnosisSafe.sol
View file @
9a48edbb
File moved
packages/contracts-bedrock/scripts/
upgrad
es/LibSort.sol
→
packages/contracts-bedrock/scripts/
librari
es/LibSort.sol
View file @
9a48edbb
File moved
packages/contracts-bedrock/scripts/outputs/DeleteOutput.s.sol
0 → 100644
View file @
9a48edbb
// 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 "../../contracts/libraries/Types.sol";
import { FeeVault } from "../../contracts/universal/FeeVault.sol";
import { L2OutputOracle } from "../../contracts/L1/L2OutputOracle.sol";
import { Predeploys } from "../../contracts/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() skipWhenNotForking external {
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 _proxyAdmin) 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();
}
}
packages/contracts-bedrock/scripts/outputs/README.md
0 → 100644
View file @
9a48edbb
## 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>
```
packages/contracts-bedrock/scripts/universal/EnhancedScript.sol
0 → 100644
View file @
9a48edbb
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { Script } from "forge-std/Script.sol";
import { Semver } from "../../contracts/universal/Semver.sol";
/**
* @title EnhancedScript
* @notice Enhances forge-std' Script.sol with some additional application-specific functionality.
* Logs simulation links using Tenderly.
*/
abstract contract EnhancedScript is Script {
/**
* @notice Helper function used to compute the hash of Semver's version string to be used in a
* comparison.
*/
function _versionHash(address _addr) internal view returns (bytes32) {
return keccak256(bytes(Semver(_addr).version()));
}
/**
* @notice Log a tenderly simulation link. The TENDERLY_USERNAME and TENDERLY_PROJECT
* environment variables will be used if they are present. The vm is staticcall'ed
* because of a compiler issue with the higher level ABI.
*/
function logSimulationLink(address _to, bytes memory _data, address _from) public view {
(, bytes memory projData) = VM_ADDRESS.staticcall(
abi.encodeWithSignature("envOr(string,string)", "TENDERLY_PROJECT", "TENDERLY_PROJECT")
);
string memory proj = abi.decode(projData, (string));
(, bytes memory userData) = VM_ADDRESS.staticcall(
abi.encodeWithSignature("envOr(string,string)", "TENDERLY_USERNAME", "TENDERLY_USERNAME")
);
string memory username = abi.decode(userData, (string));
string memory str = string.concat(
"https://dashboard.tenderly.co/",
username,
"/",
proj,
"/simulator/new?network=",
vm.toString(block.chainid),
"&contractAddress=",
vm.toString(_to),
"&rawFunctionInput=",
vm.toString(_data),
"&from=",
vm.toString(_from)
);
console.log(str);
}
}
packages/contracts-bedrock/scripts/universal/GlobalConstants.sol
0 → 100644
View file @
9a48edbb
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
/**
* @title GlobalConstants
* @notice A set of constants.
*/
contract GlobalConstants {
/**
* @notice Mainnet chain id.
*/
uint256 constant MAINNET = 1;
/**
* @notice Goerli chain id.
*/
uint256 constant GOERLI = 5;
/**
* @notice Optimism Goerli chain id.
*/
uint256 constant OP_GOERLI = 420;
}
packages/contracts-bedrock/scripts/u
pgrades
/SafeBuilder.sol
→
packages/contracts-bedrock/scripts/u
niversal
/SafeBuilder.sol
View file @
9a48edbb
...
...
@@ -2,11 +2,12 @@
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { Script } from "forge-std/Script.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { IGnosisSafe, Enum } from "./IGnosisSafe.sol";
import { LibSort } from "./LibSort.sol";
import { Semver } from "../../contracts/universal/Semver.sol";
import { LibSort } from "../libraries/LibSort.sol";
import { IGnosisSafe, Enum } from "../interfaces/IGnosisSafe.sol";
import { EnhancedScript } from "../universal/EnhancedScript.sol";
import { GlobalConstants } from "../universal/GlobalConstants.sol";
import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
/**
...
...
@@ -21,22 +22,7 @@ import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
* for the most simple user experience when using automation and no indexer.
* Run the command without the `--broadcast` flag and it will print a tenderly URL.
*/
abstract contract SafeBuilder is Script {
/**
* @notice Mainnet chain id.
*/
uint256 constant MAINNET = 1;
/**
* @notice Goerli chain id.
*/
uint256 constant GOERLI = 5;
/**
* @notice Optimism Goerli chain id.
*/
uint256 constant OP_GOERLI = 420;
abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
/**
* @notice Interface for multicall3.
*/
...
...
@@ -50,7 +36,7 @@ abstract contract SafeBuilder is Script {
/**
* @notice The entrypoint to this script.
*/
function run(address _safe, address _proxyAdmin)
external
returns (bool) {
function run(address _safe, address _proxyAdmin)
public
returns (bool) {
vm.startBroadcast();
bool success = _run(_safe, _proxyAdmin);
if (success) _postCheck();
...
...
@@ -58,12 +44,19 @@ abstract contract SafeBuilder is Script {
}
/**
* @notice The implementation of the upgrade. Split into its own function
* to allow for testability. This is subject to a race condition if
* the nonce changes by a different transaction finalizing while not
* all of the signers have used this script.
* @notice Follow up assertions to ensure that the script ran to completion.
*/
function _run(address _safe, address _proxyAdmin) public returns (bool) {
function _postCheck() internal virtual view;
/**
* @notice Creates the calldata
*/
function buildCalldata(address _proxyAdmin) internal virtual view returns (bytes memory);
/**
* @notice Internal helper function to compute the safe transaction hash.
*/
function _getTransactionHash(address _safe, address _proxyAdmin) internal returns (bytes32) {
// Ensure that the required contracts exist
require(address(multicall).code.length > 0, "multicall3 not deployed");
require(_safe.code.length > 0, "no code at safe address");
...
...
@@ -88,6 +81,23 @@ abstract contract SafeBuilder is Script {
_nonce: nonce
});
return hash;
}
/**
* @notice The implementation of the upgrade. Split into its own function
* to allow for testability. This is subject to a race condition if
* the nonce changes by a different transaction finalizing while not
* all of the signers have used this script.
*/
function _run(address _safe, address _proxyAdmin) public returns (bool) {
IGnosisSafe safe = IGnosisSafe(payable(_safe));
bytes memory data = buildCalldata(_proxyAdmin);
// Compute the safe transaction hash
bytes32 hash = _getTransactionHash(_safe, _proxyAdmin);
// Send a transaction to approve the hash
safe.approveHash(hash);
...
...
@@ -158,52 +168,6 @@ abstract contract SafeBuilder is Script {
return false;
}
/**
* @notice Log a tenderly simulation link. The TENDERLY_USERNAME and TENDERLY_PROJECT
* environment variables will be used if they are present. The vm is staticcall'ed
* because of a compiler issue with the higher level ABI.
*/
function logSimulationLink(address _to, bytes memory _data, address _from) public view {
(, bytes memory projData) = VM_ADDRESS.staticcall(
abi.encodeWithSignature("envOr(string,string)", "TENDERLY_PROJECT", "TENDERLY_PROJECT")
);
string memory proj = abi.decode(projData, (string));
(, bytes memory userData) = VM_ADDRESS.staticcall(
abi.encodeWithSignature("envOr(string,string)", "TENDERLY_USERNAME", "TENDERLY_USERNAME")
);
string memory username = abi.decode(userData, (string));
string memory str = string.concat(
"https://dashboard.tenderly.co/",
username,
"/",
proj,
"/simulator/new?network=",
vm.toString(block.chainid),
"&contractAddress=",
vm.toString(_to),
"&rawFunctionInput=",
vm.toString(_data),
"&from=",
vm.toString(_from)
);
console.log(str);
}
/**
* @notice Follow up assertions to ensure that the script ran to completion.
*/
function _postCheck() internal virtual view;
/**
* @notice Helper function used to compute the hash of Semver's version string to be used in a
* comparison.
*/
function _versionHash(address _addr) internal view returns (bytes32) {
return keccak256(bytes(Semver(_addr).version()));
}
/**
* @notice Builds the signatures by tightly packing them together.
* Ensures that they are sorted.
...
...
@@ -226,9 +190,5 @@ abstract contract SafeBuilder is Script {
return signatures;
}
/**
* @notice Creates the calldata
*/
function buildCalldata(address _proxyAdmin) internal virtual view returns (bytes memory);
}
packages/contracts-bedrock/scripts/upgrades/PostSherlock.s.sol
View file @
9a48edbb
...
...
@@ -2,10 +2,10 @@
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { SafeBuilder } from "./SafeBuilder.sol";
import { SafeBuilder } from ".
./universal
/SafeBuilder.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { IGnosisSafe, Enum } from "./IGnosisSafe.sol";
import { LibSort } from "./LibSort.sol";
import { IGnosisSafe, Enum } from ".
./interfaces
/IGnosisSafe.sol";
import { LibSort } from ".
./libraries
/LibSort.sol";
import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
import { Constants } from "../../contracts/libraries/Constants.sol";
import { SystemConfig } from "../../contracts/L1/SystemConfig.sol";
...
...
packages/contracts-bedrock/scripts/upgrades/PostSherlockL2.s.sol
View file @
9a48edbb
...
...
@@ -2,8 +2,8 @@
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { SafeBuilder } from "./SafeBuilder.sol";
import { IGnosisSafe, Enum } from "./IGnosisSafe.sol";
import { SafeBuilder } from ".
./universal
/SafeBuilder.sol";
import { IGnosisSafe, Enum } from ".
./libraries
/IGnosisSafe.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { Predeploys } from "../../contracts/libraries/Predeploys.sol";
import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment