github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/test/universal/OptimismMintableERC721Factory.t.sol (about) 1 // SPDX-License-Identifier: MIT 2 pragma solidity 0.8.15; 3 4 import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 5 import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; 6 import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; 7 import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; 8 9 contract OptimismMintableERC721Factory_Test is Bridge_Initializer { 10 OptimismMintableERC721Factory internal factory; 11 12 event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer); 13 14 function setUp() public override { 15 super.setUp(); 16 17 // Set up the token pair. 18 factory = new OptimismMintableERC721Factory(address(l2ERC721Bridge), 1); 19 20 // Label the addresses for nice traces. 21 vm.label(address(factory), "OptimismMintableERC721Factory"); 22 } 23 24 function test_constructor_succeeds() external { 25 assertEq(factory.BRIDGE(), address(l2ERC721Bridge)); 26 assertEq(factory.REMOTE_CHAIN_ID(), 1); 27 } 28 29 function test_createOptimismMintableERC721_succeeds() external { 30 address remote = address(1234); 31 address local = calculateTokenAddress(address(1234), "L2Token", "L2T"); 32 33 // Expect a token creation event. 34 vm.expectEmit(true, true, true, true); 35 emit OptimismMintableERC721Created(local, remote, alice); 36 37 // Create the token. 38 vm.prank(alice); 39 OptimismMintableERC721 created = 40 OptimismMintableERC721(factory.createOptimismMintableERC721(remote, "L2Token", "L2T")); 41 42 // Token address should be correct. 43 assertEq(address(created), local); 44 45 // Should be marked as created by the factory. 46 assertEq(factory.isOptimismMintableERC721(address(created)), true); 47 48 // Token should've been constructed correctly. 49 assertEq(created.name(), "L2Token"); 50 assertEq(created.symbol(), "L2T"); 51 assertEq(created.REMOTE_TOKEN(), remote); 52 assertEq(created.BRIDGE(), address(l2ERC721Bridge)); 53 assertEq(created.REMOTE_CHAIN_ID(), 1); 54 } 55 56 function test_createOptimismMintableERC721_sameTwice_reverts() external { 57 address remote = address(1234); 58 59 vm.prank(alice); 60 factory.createOptimismMintableERC721(remote, "L2Token", "L2T"); 61 62 vm.expectRevert(bytes("")); 63 64 vm.prank(alice); 65 factory.createOptimismMintableERC721(remote, "L2Token", "L2T"); 66 } 67 68 function test_createOptimismMintableERC721_zeroRemoteToken_reverts() external { 69 // Try to create a token with a zero remote token address. 70 vm.expectRevert("OptimismMintableERC721Factory: L1 token address cannot be address(0)"); 71 factory.createOptimismMintableERC721(address(0), "L2Token", "L2T"); 72 } 73 74 function calculateTokenAddress( 75 address _remote, 76 string memory _name, 77 string memory _symbol 78 ) 79 internal 80 view 81 returns (address) 82 { 83 bytes memory constructorArgs = abi.encode(address(l2ERC721Bridge), 1, _remote, _name, _symbol); 84 bytes memory bytecode = abi.encodePacked(type(OptimismMintableERC721).creationCode, constructorArgs); 85 bytes32 salt = keccak256(abi.encode(_remote, _name, _symbol)); 86 bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(factory), salt, keccak256(bytecode))); 87 return address(uint160(uint256(hash))); 88 } 89 }