Commit 35bbd80e authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

contracts-bedrock: fixes `OptimismMintableERC721Factory` test (#12306)

* contracts-bedrock: fixes `OptimismMintableERC721Factory` test

This contract is only used as a predeploy so it should be tested based
on the L2 genesis generation setup. Ensures that the address is stored
and labeled as part of in memory test setup, as well as updates the
tests to work based on the predeploy.

This is a small refactor to make future Standard L2 genesis work more
simple.

Also includes a small ABI fix to the `OptimismMintableERC721Factory`
since this contract has not been updated to decouple immutable naming
conventions from its ABI.

* snapshots: update

* checks: fix

* lint: fix

* typo: fix
parent b460aa27
......@@ -4,10 +4,10 @@ GasBenchMark_L1BlockInterop_SetValuesInterop:test_setL1BlockValuesInterop_benchm
GasBenchMark_L1BlockInterop_SetValuesInterop_Warm:test_setL1BlockValuesInterop_benchmark() (gas: 5099)
GasBenchMark_L1Block_SetValuesEcotone:test_setL1BlockValuesEcotone_benchmark() (gas: 158531)
GasBenchMark_L1Block_SetValuesEcotone_Warm:test_setL1BlockValuesEcotone_benchmark() (gas: 7597)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369242)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967382)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564356)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076571)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369245)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967385)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564368)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076583)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467019)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512723)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72618)
......
......@@ -212,8 +212,8 @@
"sourceCodeHash": "0x5ea7c1b0cef5609f25c4193f5795fc9ce8f3ae08dbbf2945afe38e5af58f32c3"
},
"src/universal/OptimismMintableERC721Factory.sol": {
"initCodeHash": "0x1e247d46b5ac3cc8ac6b51193917cd5b88ff00fbea7bf768c65fa35a115f8607",
"sourceCodeHash": "0x1c4bc4727f08d80e8364561b49397ee57bb485072cb004b7a430559cbfa019a6"
"initCodeHash": "0x63d2ceafd3f3b3b54e31749574563e8022fef9c6da7bb8c7a113b3dbf571cfa2",
"sourceCodeHash": "0x705e270925fcad14e805b5ec1bbbb9e78b5b44e3b128f284b0113a4d68c82ef6"
},
"src/universal/StorageSetter.sol": {
"initCodeHash": "0x21b3059e9b13b330f76d02b61f61dcfa3abf3517a0b56afa0895c4b8291740bf",
......
......@@ -41,6 +41,19 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "bridge",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
......@@ -89,6 +102,19 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "remoteChainID",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "version",
......
......@@ -7,9 +7,11 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol";
/// @title OptimismMintableERC721Factory
/// @notice Factory contract for creating OptimismMintableERC721 contracts.
contract OptimismMintableERC721Factory is ISemver {
/// @custom:legacy true
/// @notice Address of the ERC721 bridge on this network.
address public immutable BRIDGE;
/// @custom:legacy true
/// @notice Chain ID for the remote network.
uint256 public immutable REMOTE_CHAIN_ID;
......@@ -23,8 +25,8 @@ contract OptimismMintableERC721Factory is ISemver {
event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer);
/// @notice Semantic version.
/// @custom:semver 1.4.1-beta.2
string public constant version = "1.4.1-beta.2";
/// @custom:semver 1.4.1-beta.3
string public constant version = "1.4.1-beta.3";
/// @notice The semver MUST be bumped any time that there is a change in
/// the OptimismMintableERC721 token contract since this contract
......@@ -36,6 +38,16 @@ contract OptimismMintableERC721Factory is ISemver {
REMOTE_CHAIN_ID = _remoteChainId;
}
/// @notice Address of the ERC721 bridge on this network.
function bridge() external view returns (address) {
return BRIDGE;
}
/// @notice Chain ID for the remote network.
function remoteChainID() external view returns (uint256) {
return REMOTE_CHAIN_ID;
}
/// @notice Creates an instance of the standard ERC721.
/// @param _remoteToken Address of the corresponding token on the other domain.
/// @param _name ERC721 name.
......
......@@ -6,6 +6,7 @@ interface IOptimismMintableERC721Factory {
function BRIDGE() external view returns (address);
function REMOTE_CHAIN_ID() external view returns (uint256);
function bridge() external view returns (address);
function createOptimismMintableERC721(
address _remoteToken,
string memory _name,
......@@ -14,6 +15,7 @@ interface IOptimismMintableERC721Factory {
external
returns (address);
function isOptimismMintableERC721(address) external view returns (bool);
function remoteChainID() external view returns (uint256);
function version() external view returns (string memory);
function __constructor__(address _bridge, uint256 _remoteChainId) external;
......
......@@ -29,6 +29,7 @@ import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityC
import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol";
import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol";
import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol";
import { IOptimismMintableERC721Factory } from "src/universal/interfaces/IOptimismMintableERC721Factory.sol";
import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol";
import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol";
import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol";
......@@ -96,6 +97,8 @@ contract Setup {
IOptimismMintableERC20Factory l2OptimismMintableERC20Factory =
IOptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);
IL2ERC721Bridge l2ERC721Bridge = IL2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);
IOptimismMintableERC721Factory l2OptimismMintableERC721Factory =
IOptimismMintableERC721Factory(Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY);
IBaseFeeVault baseFeeVault = IBaseFeeVault(payable(Predeploys.BASE_FEE_VAULT));
ISequencerFeeVault sequencerFeeVault = ISequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET));
IL1FeeVault l1FeeVault = IL1FeeVault(payable(Predeploys.L1_FEE_VAULT));
......@@ -221,6 +224,7 @@ contract Setup {
labelPredeploy(Predeploys.L2_TO_L1_MESSAGE_PASSER);
labelPredeploy(Predeploys.SEQUENCER_FEE_WALLET);
labelPredeploy(Predeploys.L2_ERC721_BRIDGE);
labelPredeploy(Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY);
labelPredeploy(Predeploys.BASE_FEE_VAULT);
labelPredeploy(Predeploys.L1_FEE_VAULT);
labelPredeploy(Predeploys.L1_BLOCK_ATTRIBUTES);
......
......@@ -7,23 +7,13 @@ import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol
import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol";
contract OptimismMintableERC721Factory_Test is Bridge_Initializer {
OptimismMintableERC721Factory internal factory;
event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer);
function setUp() public override {
super.setUp();
// Set up the token pair.
factory = new OptimismMintableERC721Factory(address(l2ERC721Bridge), 1);
// Label the addresses for nice traces.
vm.label(address(factory), "OptimismMintableERC721Factory");
}
function test_constructor_succeeds() external view {
assertEq(factory.BRIDGE(), address(l2ERC721Bridge));
assertEq(factory.REMOTE_CHAIN_ID(), 1);
assertEq(l2OptimismMintableERC721Factory.BRIDGE(), address(l2ERC721Bridge));
assertEq(l2OptimismMintableERC721Factory.bridge(), address(l2ERC721Bridge));
assertEq(l2OptimismMintableERC721Factory.REMOTE_CHAIN_ID(), deploy.cfg().l1ChainID());
assertEq(l2OptimismMintableERC721Factory.remoteChainID(), deploy.cfg().l1ChainID());
}
function test_createOptimismMintableERC721_succeeds() external {
......@@ -31,44 +21,45 @@ contract OptimismMintableERC721Factory_Test is Bridge_Initializer {
address local = calculateTokenAddress(address(1234), "L2Token", "L2T");
// Expect a token creation event.
vm.expectEmit(true, true, true, true);
vm.expectEmit(address(l2OptimismMintableERC721Factory));
emit OptimismMintableERC721Created(local, remote, alice);
// Create the token.
vm.prank(alice);
OptimismMintableERC721 created =
OptimismMintableERC721(factory.createOptimismMintableERC721(remote, "L2Token", "L2T"));
OptimismMintableERC721 created = OptimismMintableERC721(
l2OptimismMintableERC721Factory.createOptimismMintableERC721(remote, "L2Token", "L2T")
);
// Token address should be correct.
assertEq(address(created), local);
// Should be marked as created by the factory.
assertEq(factory.isOptimismMintableERC721(address(created)), true);
assertTrue(l2OptimismMintableERC721Factory.isOptimismMintableERC721(address(created)));
// Token should've been constructed correctly.
assertEq(created.name(), "L2Token");
assertEq(created.symbol(), "L2T");
assertEq(created.REMOTE_TOKEN(), remote);
assertEq(created.BRIDGE(), address(l2ERC721Bridge));
assertEq(created.REMOTE_CHAIN_ID(), 1);
assertEq(created.REMOTE_CHAIN_ID(), deploy.cfg().l1ChainID());
}
function test_createOptimismMintableERC721_sameTwice_reverts() external {
address remote = address(1234);
vm.prank(alice);
factory.createOptimismMintableERC721(remote, "L2Token", "L2T");
l2OptimismMintableERC721Factory.createOptimismMintableERC721(remote, "L2Token", "L2T");
vm.expectRevert(bytes(""));
vm.prank(alice);
factory.createOptimismMintableERC721(remote, "L2Token", "L2T");
l2OptimismMintableERC721Factory.createOptimismMintableERC721(remote, "L2Token", "L2T");
}
function test_createOptimismMintableERC721_zeroRemoteToken_reverts() external {
// Try to create a token with a zero remote token address.
vm.expectRevert("OptimismMintableERC721Factory: L1 token address cannot be address(0)");
factory.createOptimismMintableERC721(address(0), "L2Token", "L2T");
l2OptimismMintableERC721Factory.createOptimismMintableERC721(address(0), "L2Token", "L2T");
}
function calculateTokenAddress(
......@@ -80,10 +71,13 @@ contract OptimismMintableERC721Factory_Test is Bridge_Initializer {
view
returns (address)
{
bytes memory constructorArgs = abi.encode(address(l2ERC721Bridge), 1, _remote, _name, _symbol);
bytes memory constructorArgs =
abi.encode(address(l2ERC721Bridge), deploy.cfg().l1ChainID(), _remote, _name, _symbol);
bytes memory bytecode = abi.encodePacked(type(OptimismMintableERC721).creationCode, constructorArgs);
bytes32 salt = keccak256(abi.encode(_remote, _name, _symbol));
bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(factory), salt, keccak256(bytecode)));
bytes32 hash = keccak256(
abi.encodePacked(bytes1(0xff), address(l2OptimismMintableERC721Factory), salt, keccak256(bytecode))
);
return address(uint160(uint256(hash)));
}
}
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