Commit 2389d445 authored by OptimismBot's avatar OptimismBot Committed by GitHub

Merge pull request #5553 from ethereum-optimism/refcell/verifyscript

feat(contracts-bedrock): Gnosis Safe Tx Hash Validation
parents b9ca24ef 26f8c82f
...@@ -34,14 +34,10 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants { ...@@ -34,14 +34,10 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
address[] internal approvals; address[] internal approvals;
/** /**
* @notice The entrypoint to this script. * -----------------------------------------------------------
* Virtual Functions
* -----------------------------------------------------------
*/ */
function run(address _safe, address _proxyAdmin) public returns (bool) {
vm.startBroadcast();
bool success = _run(_safe, _proxyAdmin);
if (success) _postCheck();
return success;
}
/** /**
* @notice Follow up assertions to ensure that the script ran to completion. * @notice Follow up assertions to ensure that the script ran to completion.
...@@ -56,7 +52,30 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants { ...@@ -56,7 +52,30 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
/** /**
* @notice Internal helper function to compute the safe transaction hash. * @notice Internal helper function to compute the safe transaction hash.
*/ */
function _getTransactionHash(address _safe, address _proxyAdmin) internal returns (bytes32) { function computeSafeTransactionHash(address _safe, address _proxyAdmin) public virtual returns (bytes32) {
return _getTransactionHash(_safe, _proxyAdmin);
}
/**
* -----------------------------------------------------------
* Implemented Functions
* -----------------------------------------------------------
*/
/**
* @notice The entrypoint to this script.
*/
function run(address _safe, address _proxyAdmin) public returns (bool) {
vm.startBroadcast();
bool success = _run(_safe, _proxyAdmin);
if (success) _postCheck();
return success;
}
/**
* @notice Computes the safe transaction hash for the provided safe and proxy admin.
*/
function _getTransactionHash(address _safe, address _proxyAdmin) internal view returns (bytes32) {
// Ensure that the required contracts exist // Ensure that the required contracts exist
require(address(multicall).code.length > 0, "multicall3 not deployed"); require(address(multicall).code.length > 0, "multicall3 not deployed");
require(_safe.code.length > 0, "no code at safe address"); require(_safe.code.length > 0, "no code at safe address");
...@@ -84,7 +103,6 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants { ...@@ -84,7 +103,6 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
return hash; return hash;
} }
/** /**
* @notice The implementation of the upgrade. Split into its own function * @notice The implementation of the upgrade. Split into its own function
* to allow for testability. This is subject to a race condition if * to allow for testability. This is subject to a race condition if
...@@ -189,6 +207,5 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants { ...@@ -189,6 +207,5 @@ abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
} }
return signatures; return signatures;
} }
} }
...@@ -115,24 +115,24 @@ contract PostSherlockL1 is SafeBuilder { ...@@ -115,24 +115,24 @@ contract PostSherlockL1 is SafeBuilder {
* could be added. * could be added.
*/ */
function test_script_succeeds() skipWhenNotForking external { function test_script_succeeds() skipWhenNotForking external {
address safe; address _safe;
address proxyAdmin; address _proxyAdmin;
if (block.chainid == GOERLI) { if (block.chainid == GOERLI) {
safe = 0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f; _safe = 0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f;
proxyAdmin = 0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d; _proxyAdmin = 0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d;
// Set the proxy admin for the `_postCheck` function // Set the proxy admin for the `_postCheck` function
PROXY_ADMIN = ProxyAdmin(proxyAdmin); PROXY_ADMIN = ProxyAdmin(_proxyAdmin);
} }
require(safe != address(0) && proxyAdmin != address(0)); require(_safe != address(0) && _proxyAdmin != address(0));
address[] memory owners = IGnosisSafe(payable(safe)).getOwners(); address[] memory owners = IGnosisSafe(payable(_safe)).getOwners();
for (uint256 i; i < owners.length; i++) { for (uint256 i; i < owners.length; i++) {
address owner = owners[i]; address owner = owners[i];
vm.startBroadcast(owner); vm.startBroadcast(owner);
bool success = _run(safe, proxyAdmin); bool success = _run(_safe, _proxyAdmin);
vm.stopBroadcast(); vm.stopBroadcast();
if (success) { if (success) {
......
...@@ -3,7 +3,7 @@ pragma solidity 0.8.15; ...@@ -3,7 +3,7 @@ pragma solidity 0.8.15;
import { console } from "forge-std/console.sol"; import { console } from "forge-std/console.sol";
import { SafeBuilder } from "../universal/SafeBuilder.sol"; import { SafeBuilder } from "../universal/SafeBuilder.sol";
import { IGnosisSafe, Enum } from "../libraries/IGnosisSafe.sol"; import { IGnosisSafe, Enum } from "../interfaces/IGnosisSafe.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol"; import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { Predeploys } from "../../contracts/libraries/Predeploys.sol"; import { Predeploys } from "../../contracts/libraries/Predeploys.sol";
import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol"; import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
...@@ -131,22 +131,22 @@ contract PostSherlockL2 is SafeBuilder { ...@@ -131,22 +131,22 @@ contract PostSherlockL2 is SafeBuilder {
* could be added. * could be added.
*/ */
function test_script_succeeds() skipWhenNotForking external { function test_script_succeeds() skipWhenNotForking external {
address safe; address _safe;
address proxyAdmin; address _proxyAdmin;
if (block.chainid == OP_GOERLI) { if (block.chainid == OP_GOERLI) {
safe = 0xE534ccA2753aCFbcDBCeB2291F596fc60495257e; _safe = 0xE534ccA2753aCFbcDBCeB2291F596fc60495257e;
proxyAdmin = 0x4200000000000000000000000000000000000018; _proxyAdmin = 0x4200000000000000000000000000000000000018;
} }
require(safe != address(0) && proxyAdmin != address(0)); require(_safe != address(0) && _proxyAdmin != address(0));
address[] memory owners = IGnosisSafe(payable(safe)).getOwners(); address[] memory owners = IGnosisSafe(payable(_safe)).getOwners();
for (uint256 i; i < owners.length; i++) { for (uint256 i; i < owners.length; i++) {
address owner = owners[i]; address owner = owners[i];
vm.startBroadcast(owner); vm.startBroadcast(owner);
bool success = _run(safe, proxyAdmin); bool success = _run(_safe, _proxyAdmin);
vm.stopBroadcast(); vm.stopBroadcast();
if (success) { if (success) {
......
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