Commit 86678504 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #7611 from ethereum-optimism/ctb/storage-setter

contracts-bedrock: `StorageSetter` contract
parents 67d34bdd 487b26fe
......@@ -40,5 +40,6 @@
"Safe",
"SafeProxyFactory",
"DelayedVetoable",
"ISemver"
"ISemver",
"StorageSetter"
]
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const StorageSetterStorageLayoutJSON = "{\"storage\":null,\"types\":{}}"
var StorageSetterStorageLayout = new(solc.StorageLayout)
var StorageSetterDeployedBin = "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c8063a6ed563e1161005b578063a6ed563e1461011c578063bd02d0f51461011c578063ca446dd914610138578063e2a4853a146100bf57600080fd5b806321f8a721146100825780634e91db08146100bf57806354fd4d50146100d3575b600080fd5b610095610090366004610156565b610146565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100d16100cd36600461016f565b9055565b005b61010f6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100b69190610191565b61012a610090366004610156565b6040519081526020016100b6565b6100d16100cd366004610204565b6000610150825490565b92915050565b60006020828403121561016857600080fd5b5035919050565b6000806040838503121561018257600080fd5b50508035926020909101359150565b600060208083528351808285015260005b818110156101be578581018301518582016040015282016101a2565b818111156101d0576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000806040838503121561021757600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811461024257600080fd5b80915050925092905056fea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(StorageSetterStorageLayoutJSON), StorageSetterStorageLayout); err != nil {
panic(err)
}
layouts["StorageSetter"] = StorageSetterStorageLayout
deployedBytecodes["StorageSetter"] = StorageSetterDeployedBin
}
......@@ -658,9 +658,9 @@ SequencerFeeVault_Test:test_withdraw_toL1_succeeds() (gas: 171675)
SetPrevBaseFee_Test:test_setPrevBaseFee_succeeds() (gas: 11549)
StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 49936)
StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33072)
Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31799, ~: 31799)
Storage_Roundtrip_Test:test_setGetBytes32_succeeds(bytes32,bytes32) (runs: 64, μ: 31643, ~: 31643)
Storage_Roundtrip_Test:test_setGetUint_succeeds(bytes32,uint256) (runs: 64, μ: 30998, ~: 31620)
Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31199, ~: 31821)
Storage_Roundtrip_Test:test_setGetBytes32_succeeds(bytes32,bytes32) (runs: 64, μ: 31598, ~: 31598)
Storage_Roundtrip_Test:test_setGetUint_succeeds(bytes32,uint256) (runs: 64, μ: 31042, ~: 31664)
SystemConfig_Initialize_Test:test_initialize_events_succeeds() (gas: 71972)
SystemConfig_Initialize_Test:test_initialize_startBlockNoop_reverts() (gas: 81247)
SystemConfig_Initialize_Test:test_initialize_startBlockOverride_succeeds() (gas: 65143)
......
......@@ -35,6 +35,7 @@ import { MIPS } from "src/cannon/MIPS.sol";
import { BlockOracle } from "src/dispute/BlockOracle.sol";
import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol";
import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol";
import { StorageSetter } from "src/universal/StorageSetter.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
import { Chains } from "./Chains.sol";
......@@ -999,4 +1000,13 @@ contract Deploy is Deployer {
);
}
}
/// @notice Deploy the StorageSetter contract, used for upgrades.
function deployStorageSetter() public broadcast returns (address addr_) {
StorageSetter setter = new StorageSetter{ salt: implSalt() }();
console.log("StorageSetter deployed at: %s", address(setter));
string memory version = setter.version();
console.log("StorageSetter version: %s", version);
addr_ = address(setter);
}
}
......@@ -31,5 +31,6 @@
"src/universal/OptimismMintableERC20.sol": "0x17fe6e955dc7e9e480e57bc62c227206838b204dcb660b8cb8f6f217319a22ba",
"src/universal/OptimismMintableERC20Factory.sol": "0x684a9445515e3797722b211e2c0d6a94b6244d6fa028cd2825a31538ef2dc59c",
"src/universal/OptimismMintableERC721.sol": "0x4c73bf8474fa7eb091796a4db7e57bc5f26d50a3d1cfcb78d5efa47ced5ced2b",
"src/universal/OptimismMintableERC721Factory.sol": "0x935fd97018b6ef10fa813d9d43ab7a77c80885f7a8d7feb430097645cb2abd2c"
"src/universal/OptimismMintableERC721Factory.sol": "0x935fd97018b6ef10fa813d9d43ab7a77c80885f7a8d7feb430097645cb2abd2c",
"src/universal/StorageSetter.sol": "0x6372647d8a67d243bc2fb40d2c4bf5807022d94d52d9423cfed27a7d57918635"
}
\ No newline at end of file
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { ISemver } from "src/universal/ISemver.sol";
import { Storage } from "src/libraries/Storage.sol";
/// @title StorageSetter
/// @notice A simple contract that allows setting arbitrary storage slots.
/// WARNING: this contract is not safe to be called by untrusted parties.
/// It is only meant as an intermediate step during upgrades.
contract StorageSetter is ISemver {
/// @notice Semantic version.
/// @custom:semver 1.0.0
string public constant version = "1.0.0";
/// @notice Stores a bytes32 `_value` at `_slot`. Any storage slots that
/// are packed should be set through this interface.
function setBytes32(bytes32 _slot, bytes32 _value) public {
Storage.setBytes32(_slot, _value);
}
/// @notice Retrieves a bytes32 value from `_slot`.
function getBytes32(bytes32 _slot) external view returns (bytes32) {
return Storage.getBytes32(_slot);
}
/// @notice Stores a uint256 `_value` at `_slot`.
function setUint(bytes32 _slot, uint256 _value) public {
Storage.setUint(_slot, _value);
}
/// @notice Retrieves a uint256 value from `_slot`.
function getUint(bytes32 _slot) external view returns (uint256) {
return Storage.getUint(_slot);
}
/// @notice Stores an address `_value` at `_slot`.
function setAddress(bytes32 _slot, address _address) public {
Storage.setAddress(_slot, _address);
}
/// @notice Retrieves an address value from `_slot`.
function getAddress(bytes32 _slot) external view returns (address) {
return Storage.getAddress(_slot);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
pragma solidity 0.8.15;
// Target contract
import { Storage } from "src/libraries/Storage.sol";
import { StorageSetter } from "src/universal/StorageSetter.sol";
import { Test } from "forge-std/Test.sol";
import { console } from "forge-std/console.sol";
/// @title StorageWrapper
/// @notice StorageWrapper wraps the Storage library for testing purposes.
/// It exists to prevent storage collisions with the `Test` contract.
contract StorageWrapper {
function getAddress(bytes32 _slot) external view returns (address) {
return Storage.getAddress(_slot);
}
function setAddress(bytes32 _slot, address _address) external {
Storage.setAddress(_slot, _address);
}
function getUint(bytes32 _slot) external view returns (uint256) {
return Storage.getUint(_slot);
}
function setUint(bytes32 _slot, uint256 _value) external {
Storage.setUint(_slot, _value);
}
function getBytes32(bytes32 _slot) external view returns (bytes32) {
return Storage.getBytes32(_slot);
}
function setBytes32(bytes32 _slot, bytes32 _value) external {
Storage.setBytes32(_slot, _value);
}
}
/// @title Storage_Roundtrip_Test
/// @notice Tests the storage setting and getting through the StorageSetter contract.
/// This contract simply wraps the Storage library, this is required as to
/// not poison the storage of the `Test` contract.
contract Storage_Roundtrip_Test is Test {
StorageWrapper wrapper;
StorageSetter setter;
function setUp() external {
wrapper = new StorageWrapper();
setter = new StorageSetter();
}
function test_setGetUint_succeeds(bytes32 slot, uint256 num) external {
wrapper.setUint(slot, num);
assertEq(wrapper.getUint(slot), num);
assertEq(num, uint256(vm.load(address(wrapper), slot)));
setter.setUint(slot, num);
assertEq(setter.getUint(slot), num);
assertEq(num, uint256(vm.load(address(setter), slot)));
}
function test_setGetAddress_succeeds(bytes32 slot, address addr) external {
wrapper.setAddress(slot, addr);
assertEq(wrapper.getAddress(slot), addr);
assertEq(addr, address(uint160(uint256(vm.load(address(wrapper), slot)))));
setter.setAddress(slot, addr);
assertEq(setter.getAddress(slot), addr);
assertEq(addr, address(uint160(uint256(vm.load(address(setter), slot)))));
}
function test_setGetBytes32_succeeds(bytes32 slot, bytes32 hash) external {
wrapper.setBytes32(slot, hash);
assertEq(wrapper.getBytes32(slot), hash);
assertEq(hash, vm.load(address(wrapper), slot));
setter.setBytes32(slot, hash);
assertEq(setter.getBytes32(slot), hash);
assertEq(hash, vm.load(address(setter), slot));
}
}
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