Skip to content

Commit

Permalink
Merge pull request #8700 from ethereum-optimism/ctb/OptimismMintableE…
Browse files Browse the repository at this point in the history
…RC20Factory-immutable

contracts-bedrock: move immutables to storage for OptimismMintableERC20Factory
  • Loading branch information
tynes authored Jan 11, 2024
2 parents 911dc10 + 9eda162 commit 5841705
Show file tree
Hide file tree
Showing 15 changed files with 398 additions and 81 deletions.
163 changes: 159 additions & 4 deletions op-bindings/bindings/optimismmintableerc20factory.go

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions op-bindings/bindings/optimismmintableerc20factory_more.go

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions op-chain-ops/cmd/check-l2/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ var (
// errAlreadyInitialized represents a revert from when a contract is already initialized.
// This error is used to assert with `eth_call` on contracts that are `Initializable`
errAlreadyInitialized = errors.New("Initializable: contract is already initialized")
// errInvalidInitializing represents when the initializing value is not set to the expected value.
// This is an assertion on `_initializing`. We do not care about the value of `_initialized`.
errInvalidInitializing = errors.New("invalid initializing value")
)

// Default script for checking that L2 has been configured correctly. This should be extended in the future
Expand Down Expand Up @@ -684,6 +687,33 @@ func checkOptimismMintableERC20Factory(addr common.Address, client *ethclient.Cl
}
log.Info("OptimismMintableERC20Factory", "bridge", bridge.Hex())

initialized, err := getInitialized("OptimismMintableERC20Factory", addr, client)
if err != nil {
return err
}
log.Info("OptimismMintableERC20Factory", "_initialized", initialized)

abi, err := bindings.OptimismMintableERC20FactoryMetaData.GetAbi()
if err != nil {
return err
}
calldata, err := abi.Pack("initialize", bridge)
if err != nil {
return err
}
if err := checkAlreadyInitialized(addr, calldata, client); err != nil {
return err
}

initializing, err := getInitializing("OptimismMintableERC20Factory", addr, client)
if err != nil {
return err
}
log.Info("OptimismMintableERC20Factory", "_initializing", initializing)
if initializing {
return fmt.Errorf("%w: %t", errInvalidInitializing, initializing)
}

version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
Expand Down
13 changes: 7 additions & 6 deletions op-chain-ops/genesis/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -770,12 +770,8 @@ func NewL2ImmutableConfig(config *DeployConfig, block *types.Block) (*immutables
Bridge: predeploys.L2ERC721BridgeAddr,
RemoteChainId: new(big.Int).SetUint64(config.L1ChainID),
},
OptimismMintableERC20Factory: struct {
Bridge common.Address
}{
Bridge: predeploys.L2StandardBridgeAddr,
},
ProxyAdmin: struct{}{},
OptimismMintableERC20Factory: struct{}{},
ProxyAdmin: struct{}{},
BaseFeeVault: struct {
Recipient common.Address
MinWithdrawalAmount *big.Int
Expand Down Expand Up @@ -838,6 +834,11 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.Storage
"_initialized": 1,
"_initializing": false,
}
storage["OptimismMintableERC20Factory"] = state.StorageValues{
"_initialized": 1,
"_initializing": false,
"bridge": predeploys.L2StandardBridgeAddr,
}
storage["L1Block"] = state.StorageValues{
"number": block.Number(),
"timestamp": block.Time(),
Expand Down
27 changes: 8 additions & 19 deletions op-chain-ops/immutables/immutables.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/ethereum/go-ethereum/core/types"

"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/deployer"
)

Expand All @@ -36,15 +35,13 @@ type PredeploysImmutableConfig struct {
MinWithdrawalAmount *big.Int
WithdrawalNetwork uint8
}
OptimismMintableERC20Factory struct {
Bridge common.Address
}
L1BlockNumber struct{}
GasPriceOracle struct{}
L1Block struct{}
GovernanceToken struct{}
LegacyMessagePasser struct{}
L2ERC721Bridge struct {
OptimismMintableERC20Factory struct{}
L1BlockNumber struct{}
GasPriceOracle struct{}
L1Block struct{}
GovernanceToken struct{}
LegacyMessagePasser struct{}
L2ERC721Bridge struct {
OtherBridge common.Address
Messenger common.Address
}
Expand Down Expand Up @@ -234,15 +231,7 @@ func l2ImmutableDeployer(backend *backends.SimulatedBackend, opts *bind.Transact
}
_, tx, _, err = bindings.DeployL1FeeVault(opts, backend, recipient, minimumWithdrawalAmount, withdrawalNetwork)
case "OptimismMintableERC20Factory":
bridge, ok := deployment.Args[0].(common.Address)
if !ok {
return nil, fmt.Errorf("invalid type for bridge")
}
// Sanity check that the argument is correct
if bridge != predeploys.L2StandardBridgeAddr {
return nil, fmt.Errorf("invalid bridge address")
}
_, tx, _, err = bindings.DeployOptimismMintableERC20Factory(opts, backend, bridge)
_, tx, _, err = bindings.DeployOptimismMintableERC20Factory(opts, backend)
case "L2ERC721Bridge":
otherBridge, ok := deployment.Args[0].(common.Address)
if !ok {
Expand Down
8 changes: 2 additions & 6 deletions op-chain-ops/immutables/immutables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,8 @@ func TestBuildOptimism(t *testing.T) {
Bridge: predeploys.L2StandardBridgeAddr,
RemoteChainId: big.NewInt(1),
},
OptimismMintableERC20Factory: struct {
Bridge common.Address
}{
Bridge: predeploys.L2StandardBridgeAddr,
},
ProxyAdmin: struct{}{},
OptimismMintableERC20Factory: struct{}{},
ProxyAdmin: struct{}{},
BaseFeeVault: struct {
Recipient common.Address
MinWithdrawalAmount *big.Int
Expand Down
31 changes: 28 additions & 3 deletions op-chain-ops/upgrades/l1.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ const (
// upgradeAndCall represents the signature of the upgradeAndCall function
// on the ProxyAdmin contract.
upgradeAndCall = "upgradeAndCall(address,address,bytes)"
// upgrade represents the signature of the upgrade function on the ProxyAdmin contract.
upgrade = "upgrade(address,address)"

method = "setBytes32"
)
Expand Down Expand Up @@ -444,13 +442,40 @@ func OptimismMintableERC20Factory(batch *safe.Batch, implementations superchain.
}
}

optimismMintableERC20FactoryABI, err := bindings.OptimismMintableERC20FactoryMetaData.GetAbi()
if err != nil {
return err
}

optimismMintableERC20Factory, err := bindings.NewOptimismMintableERC20FactoryCaller(common.HexToAddress(list.OptimismMintableERC20FactoryProxy.String()), backend)
if err != nil {
return err
}

bridge, err := optimismMintableERC20Factory.Bridge(&bind.CallOpts{})
if err != nil {
return err
}

if config != nil {
if bridge != config.L1StandardBridgeProxy {
return fmt.Errorf("upgrading OptimismMintableERC20Factory: Bridge address doesn't match config")
}
}

calldata, err := optimismMintableERC20FactoryABI.Pack("initialize", bridge)
if err != nil {
return err
}

args := []any{
common.HexToAddress(list.OptimismMintableERC20FactoryProxy.String()),
common.HexToAddress(implementations.OptimismMintableERC20Factory.Address.String()),
calldata,
}

proxyAdmin := common.HexToAddress(list.ProxyAdmin.String())
if err := batch.AddCall(proxyAdmin, common.Big0, upgrade, args, proxyAdminABI); err != nil {
if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil {
return err
}

Expand Down
14 changes: 10 additions & 4 deletions packages/contracts-bedrock/scripts/ChainAssertions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ library ChainAssertions {
_l2OutputOracleStartingTimestamp: _l2OutputOracleStartingTimestamp,
_isProxy: true
});
checkOptimismMintableERC20Factory(_prox);
checkOptimismMintableERC20Factory({ _contracts: _prox, _isProxy: true });
checkL1ERC721Bridge({ _contracts: _prox, _isProxy: true });
checkOptimismPortal({ _contracts: _prox, _cfg: _cfg, _isProxy: true });
checkProtocolVersions({ _contracts: _prox, _cfg: _cfg, _isProxy: true });
Expand Down Expand Up @@ -155,11 +155,17 @@ library ChainAssertions {
}

/// @notice Asserts that the OptimismMintableERC20Factory is setup correctly
function checkOptimismMintableERC20Factory(Types.ContractSet memory _contracts) internal view {
function checkOptimismMintableERC20Factory(Types.ContractSet memory _contracts, bool _isProxy) internal view {
console.log("Running chain assertions on the OptimismMintableERC20Factory");
OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(_contracts.OptimismMintableERC20Factory);
require(factory.BRIDGE() == _contracts.L1StandardBridge);
require(factory.bridge() == _contracts.L1StandardBridge);

if (_isProxy) {
require(factory.BRIDGE() == _contracts.L1StandardBridge);
require(factory.bridge() == _contracts.L1StandardBridge);
} else {
require(factory.BRIDGE() == address(0));
require(factory.bridge() == address(0));
}
}

/// @notice Asserts that the L1ERC721Bridge is setup correctly
Expand Down
19 changes: 8 additions & 11 deletions packages/contracts-bedrock/scripts/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -532,9 +532,7 @@ contract Deploy is Deployer {
/// @notice Deploy the OptimismMintableERC20Factory
function deployOptimismMintableERC20Factory() public broadcast returns (address addr_) {
console.log("Deploying OptimismMintableERC20Factory implementation");
address l1standardBridgeProxy = mustGetAddress("L1StandardBridgeProxy");
OptimismMintableERC20Factory factory =
new OptimismMintableERC20Factory{ salt: _implSalt() }({ _bridge: l1standardBridgeProxy });
OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory{ salt: _implSalt() }();

save("OptimismMintableERC20Factory", address(factory));
console.log("OptimismMintableERC20Factory deployed at %s", address(factory));
Expand All @@ -544,7 +542,7 @@ contract Deploy is Deployer {
// are always proxies.
Types.ContractSet memory contracts = _proxiesUnstrict();
contracts.OptimismMintableERC20Factory = address(factory);
ChainAssertions.checkOptimismMintableERC20Factory(contracts);
ChainAssertions.checkOptimismMintableERC20Factory({ _contracts: contracts, _isProxy: false });

addr_ = address(factory);
}
Expand Down Expand Up @@ -802,22 +800,21 @@ contract Deploy is Deployer {
/// @notice Ininitialize the OptimismMintableERC20Factory
function initializeOptimismMintableERC20Factory() public broadcast {
console.log("Upgrading and initializing OptimismMintableERC20Factory proxy");
address proxyAdmin = mustGetAddress("ProxyAdmin");
address optimismMintableERC20FactoryProxy = mustGetAddress("OptimismMintableERC20FactoryProxy");
address optimismMintableERC20Factory = mustGetAddress("OptimismMintableERC20Factory");
address l1StandardBridgeProxy = mustGetAddress("L1StandardBridgeProxy");

_callViaSafe({
_target: proxyAdmin,
_data: abi.encodeCall(
ProxyAdmin.upgrade, (payable(optimismMintableERC20FactoryProxy), optimismMintableERC20Factory)
)
_upgradeAndCallViaSafe({
_proxy: payable(optimismMintableERC20FactoryProxy),
_implementation: optimismMintableERC20Factory,
_innerCallData: abi.encodeCall(OptimismMintableERC20Factory.initialize, (l1StandardBridgeProxy))
});

OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(optimismMintableERC20FactoryProxy);
string memory version = factory.version();
console.log("OptimismMintableERC20Factory version: %s", version);

ChainAssertions.checkOptimismMintableERC20Factory(_proxies());
ChainAssertions.checkOptimismMintableERC20Factory({ _contracts: _proxies(), _isProxy: true });
}

/// @notice initializeL1CrossDomainMessenger
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@
"sourceCodeHash": "0x52737b23e99bf79dd2c23196b3298e80aa41f740efc6adc7916e696833eb546a"
},
"src/universal/OptimismMintableERC20Factory.sol": {
"initCodeHash": "0x786f4d03cf19cf3af728966a8b22385e178e2021f20b410032c195bbc57e1e7c",
"sourceCodeHash": "0x76556319925ee2bbec0eeaddcce8904b602507ed5edbcc82a1afe920b46f1840"
"initCodeHash": "0x2b6abdf0592028c5babc4b3eb808e7dc36e9d7257a56ddcb10a96b9bb0cc651c",
"sourceCodeHash": "0xfe880585d89547c5568c653b3b519e058ea8c339c81f2f3a70791197d8ef865d"
},
"src/universal/OptimismMintableERC721.sol": {
"initCodeHash": "0xb400f430acf4d65bee9635e4935a6e1e3a0284fc50aea40ad8b7818dc826f31c",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
[
{
"inputs": [
{
"internalType": "address",
"name": "_bridge",
"type": "address"
}
],
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
Expand Down Expand Up @@ -128,6 +122,19 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_bridge",
"type": "address"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "version",
Expand All @@ -141,6 +148,19 @@
"stateMutability": "view",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint8",
"name": "version",
"type": "uint8"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,30 @@
[]
[
{
"bytes": "1",
"label": "_initialized",
"offset": 0,
"slot": "0",
"type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "bool"
},
{
"bytes": "20",
"label": "bridge",
"offset": 2,
"slot": "0",
"type": "address"
},
{
"bytes": "1568",
"label": "__gap",
"offset": 0,
"slot": "1",
"type": "uint256[49]"
}
]
Loading

0 comments on commit 5841705

Please sign in to comment.