Commit 13b06bb3 authored by Mark Tyneway's avatar Mark Tyneway

contracts-bedrock: refactor for more simple `Initializable` tests

Make the ERC721Bridge test setup be part of the same process as the
StandardBridge setup so that its possible to have the entire L1 system
set up in a single unit test block. This makes writing tests that
touch all of the system L1 contracts much more easy. These changes
were done with some find and replaces.
parent b6104508
......@@ -447,9 +447,9 @@ contract Bridge_Initializer is Messenger_Initializer {
}
}
contract ERC721Bridge_Initializer is Messenger_Initializer {
L1ERC721Bridge L1Bridge;
L2ERC721Bridge L2Bridge;
contract ERC721Bridge_Initializer is Bridge_Initializer {
L1ERC721Bridge L1NFTBridge;
L2ERC721Bridge L2NFTBridge;
function setUp() public virtual override {
super.setUp();
......@@ -463,10 +463,10 @@ contract ERC721Bridge_Initializer is Messenger_Initializer {
address(l1BridgeImpl), abi.encodeCall(L1ERC721Bridge.initialize, (CrossDomainMessenger(L1Messenger)))
);
L1Bridge = L1ERC721Bridge(address(l1BridgeProxy));
L1NFTBridge = L1ERC721Bridge(address(l1BridgeProxy));
// Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address.
L2ERC721Bridge l2BridgeImpl = new L2ERC721Bridge(address(L1Bridge));
L2ERC721Bridge l2BridgeImpl = new L2ERC721Bridge(address(L1NFTBridge));
Proxy l2BridgeProxy = new Proxy(multisig);
vm.etch(Predeploys.L2_ERC721_BRIDGE, address(l2BridgeProxy).code);
......@@ -480,11 +480,11 @@ contract ERC721Bridge_Initializer is Messenger_Initializer {
);
// Set up a reference to the L2ERC721Bridge.
L2Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);
L2NFTBridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);
// Label the L1 and L2 bridges.
vm.label(address(L1Bridge), "L1ERC721Bridge");
vm.label(address(L2Bridge), "L2ERC721Bridge");
vm.label(address(L1NFTBridge), "L1ERC721Bridge");
vm.label(address(L2NFTBridge), "L2ERC721Bridge");
}
}
......
......@@ -56,15 +56,15 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Approve the bridge to transfer the token.
vm.prank(alice);
localToken.approve(address(L1Bridge), tokenId);
localToken.approve(address(L1NFTBridge), tokenId);
}
/// @dev Tests that the constructor sets the correct values.
function test_constructor_succeeds() public {
assertEq(address(L1Bridge.MESSENGER()), address(L1Messenger));
assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE);
assertEq(address(L1Bridge.messenger()), address(L1Messenger));
assertEq(address(L1Bridge.otherBridge()), Predeploys.L2_ERC721_BRIDGE);
assertEq(address(L1NFTBridge.MESSENGER()), address(L1Messenger));
assertEq(address(L1NFTBridge.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE);
assertEq(address(L1NFTBridge.messenger()), address(L1Messenger));
assertEq(address(L1NFTBridge.otherBridge()), Predeploys.L2_ERC721_BRIDGE);
}
/// @dev Tests that the ERC721 can be bridged successfully.
......@@ -75,7 +75,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encodeCall(
L1Messenger.sendMessage,
(
address(L2Bridge),
address(L2NFTBridge),
abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721,
(address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678")
......@@ -91,11 +91,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
L1Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), true);
assertEq(localToken.ownerOf(tokenId), address(L1Bridge));
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), true);
assertEq(localToken.ownerOf(tokenId), address(L1NFTBridge));
}
/// @dev Tests that the ERC721 bridge reverts for non externally owned accounts.
......@@ -104,10 +104,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.etch(alice, hex"01");
vm.prank(alice);
vm.expectRevert("ERC721Bridge: account is not externally owned");
L1Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -116,10 +116,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert();
L1Bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678");
L1NFTBridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -128,10 +128,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)");
L1Bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678");
L1NFTBridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -140,10 +140,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("ERC721: transfer from incorrect owner");
L1Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -172,11 +172,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
L1Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
L1NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), true);
assertEq(localToken.ownerOf(tokenId), address(L1Bridge));
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), true);
assertEq(localToken.ownerOf(tokenId), address(L1NFTBridge));
}
/// @dev Tests that the ERC721 bridge reverts for non externally owned accounts
......@@ -185,10 +185,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert();
L1Bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex"5678");
L1NFTBridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -198,10 +198,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)");
L1Bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678");
L1NFTBridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -211,10 +211,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("ERC721: transfer from incorrect owner");
L1Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
L1NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -222,7 +222,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_finalizeBridgeERC721_succeeds() external {
// Bridge the token.
vm.prank(alice);
L1Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
......@@ -235,10 +235,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encode(Predeploys.L2_ERC721_BRIDGE)
);
vm.prank(address(L1Messenger));
L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
// Token is not locked in the bridge.
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -248,7 +248,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Finalize a withdrawal.
vm.prank(alice);
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that the ERC721 bridge finalize reverts when not called
......@@ -260,7 +260,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
);
vm.prank(address(L1Messenger));
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that the ERC721 bridge finalize reverts when the local token
......@@ -274,7 +274,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
);
vm.prank(address(L1Messenger));
vm.expectRevert("L1ERC721Bridge: local token cannot be self");
L1Bridge.finalizeBridgeERC721(address(L1Bridge), address(remoteToken), alice, alice, tokenId, hex"5678");
L1NFTBridge.finalizeBridgeERC721(address(L1NFTBridge), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that the ERC721 bridge finalize reverts when the remote token
......@@ -288,6 +288,6 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
);
vm.prank(address(L1Messenger));
vm.expectRevert("L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge");
L1Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
}
......@@ -61,22 +61,22 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
super.setUp();
remoteToken = new TestERC721();
localToken = new TestMintableERC721(address(L2Bridge), address(remoteToken));
localToken = new TestMintableERC721(address(L2NFTBridge), address(remoteToken));
// Mint alice a token.
localToken.mint(alice, tokenId);
// Approve the bridge to transfer the token.
vm.prank(alice);
localToken.approve(address(L2Bridge), tokenId);
localToken.approve(address(L2NFTBridge), tokenId);
}
/// @dev Tests that the constructor sets the correct variables.
function test_constructor_succeeds() public {
assertEq(address(L2Bridge.MESSENGER()), address(L2Messenger));
assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge));
assertEq(address(L2Bridge.messenger()), address(L2Messenger));
assertEq(address(L2Bridge.otherBridge()), address(L1Bridge));
assertEq(address(L2NFTBridge.MESSENGER()), address(L2Messenger));
assertEq(address(L2NFTBridge.OTHER_BRIDGE()), address(L1NFTBridge));
assertEq(address(L2NFTBridge.messenger()), address(L2Messenger));
assertEq(address(L2NFTBridge.otherBridge()), address(L1NFTBridge));
}
/// @dev Tests that `bridgeERC721` correctly bridges a token and
......@@ -88,7 +88,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encodeCall(
L2Messenger.sendMessage,
(
address(L1Bridge),
address(L1NFTBridge),
abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721,
(address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678")
......@@ -104,7 +104,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
L2Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is burned.
vm.expectRevert("ERC721: invalid token ID");
......@@ -117,7 +117,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.etch(alice, hex"01");
vm.prank(alice);
vm.expectRevert("ERC721Bridge: account is not externally owned");
L2Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -128,7 +128,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert();
L2Bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678");
L2NFTBridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -139,7 +139,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)");
L2Bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678");
L2NFTBridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -150,7 +150,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner");
L2Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -165,7 +165,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encodeCall(
L2Messenger.sendMessage,
(
address(L1Bridge),
address(L1NFTBridge),
abi.encodeCall(
L1ERC721Bridge.finalizeBridgeERC721,
(address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678")
......@@ -181,7 +181,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
L2Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
L2NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is burned.
vm.expectRevert("ERC721: invalid token ID");
......@@ -193,7 +193,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert();
L2Bridge.bridgeERC721To(address(0), address(L1Bridge), bob, tokenId, 1234, hex"5678");
L2NFTBridge.bridgeERC721To(address(0), address(L1NFTBridge), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -204,7 +204,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)");
L2Bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678");
L2NFTBridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -215,7 +215,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner");
L2Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
L2NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -225,7 +225,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_finalizeBridgeERC721_succeeds() external {
// Bridge the token.
vm.prank(alice);
L2Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
......@@ -235,10 +235,10 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(L1Bridge)
abi.encode(L1NFTBridge)
);
vm.prank(address(L2Messenger));
L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -252,18 +252,18 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the non-compliant token.
vm.prank(alice);
L2Bridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex"5678");
L2NFTBridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex"5678");
// Attempt to finalize the withdrawal. Should revert because the token does not claim
// to be compliant with the `IOptimismMintableERC721` interface.
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(L1Bridge)
abi.encode(L1NFTBridge)
);
vm.prank(address(L2Messenger));
vm.expectRevert("L2ERC721Bridge: local token interface is not compliant");
L2Bridge.finalizeBridgeERC721(
L2NFTBridge.finalizeBridgeERC721(
address(address(nonCompliantToken)), address(address(0x01)), alice, alice, tokenId, hex"5678"
);
}
......@@ -273,7 +273,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Finalize a withdrawal.
vm.prank(alice);
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge.
......@@ -284,7 +284,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
);
vm.prank(address(L2Messenger));
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that `finalizeBridgeERC721` reverts when the local token is the
......@@ -294,11 +294,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge))
abi.encode(address(L1NFTBridge))
);
vm.prank(address(L2Messenger));
vm.expectRevert("L2ERC721Bridge: local token cannot be self");
L2Bridge.finalizeBridgeERC721(address(L2Bridge), address(remoteToken), alice, alice, tokenId, hex"5678");
L2NFTBridge.finalizeBridgeERC721(address(L2NFTBridge), address(remoteToken), alice, alice, tokenId, hex"5678");
}
/// @dev Tests that `finalizeBridgeERC721` reverts when already finalized.
......@@ -307,11 +307,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge))
abi.encode(address(L1NFTBridge))
);
vm.prank(address(L2Messenger));
vm.expectRevert("ERC721: token already minted");
L2Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
}
}
......
......@@ -9,8 +9,8 @@ import { ERC721Bridge_Initializer } from "./CommonTest.t.sol";
import { OptimismMintableERC721, IOptimismMintableERC721 } from "../src/universal/OptimismMintableERC721.sol";
contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
ERC721 internal L1Token;
OptimismMintableERC721 internal L2Token;
ERC721 internal L1NFT;
OptimismMintableERC721 internal L2NFT;
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
......@@ -22,41 +22,41 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
super.setUp();
// Set up the token pair.
L1Token = new ERC721("L1Token", "L1T");
L2Token = new OptimismMintableERC721(
address(L2Bridge),
L1NFT = new ERC721("L1NFT", "L1T");
L2NFT = new OptimismMintableERC721(
address(L2NFTBridge),
1,
address(L1Token),
"L2Token",
address(L1NFT),
"L2NFT",
"L2T"
);
// Label the addresses for nice traces.
vm.label(address(L1Token), "L1ERC721Token");
vm.label(address(L2Token), "L2ERC721Token");
vm.label(address(L1NFT), "L1ERC721Token");
vm.label(address(L2NFT), "L2ERC721Token");
}
function test_constructor_succeeds() external {
assertEq(L2Token.name(), "L2Token");
assertEq(L2Token.symbol(), "L2T");
assertEq(L2Token.remoteToken(), address(L1Token));
assertEq(L2Token.bridge(), address(L2Bridge));
assertEq(L2Token.remoteChainId(), 1);
assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));
assertEq(L2Token.BRIDGE(), address(L2Bridge));
assertEq(L2Token.REMOTE_CHAIN_ID(), 1);
assertEq(L2NFT.name(), "L2NFT");
assertEq(L2NFT.symbol(), "L2T");
assertEq(L2NFT.remoteToken(), address(L1NFT));
assertEq(L2NFT.bridge(), address(L2NFTBridge));
assertEq(L2NFT.remoteChainId(), 1);
assertEq(L2NFT.REMOTE_TOKEN(), address(L1NFT));
assertEq(L2NFT.BRIDGE(), address(L2NFTBridge));
assertEq(L2NFT.REMOTE_CHAIN_ID(), 1);
}
/// @notice Ensure that the contract supports the expected interfaces.
function test_supportsInterfaces_succeeds() external {
// Checks if the contract supports the IOptimismMintableERC721 interface.
assertTrue(L2Token.supportsInterface(type(IOptimismMintableERC721).interfaceId));
assertTrue(L2NFT.supportsInterface(type(IOptimismMintableERC721).interfaceId));
// Checks if the contract supports the IERC721Enumerable interface.
assertTrue(L2Token.supportsInterface(type(IERC721Enumerable).interfaceId));
assertTrue(L2NFT.supportsInterface(type(IERC721Enumerable).interfaceId));
// Checks if the contract supports the IERC721 interface.
assertTrue(L2Token.supportsInterface(type(IERC721).interfaceId));
assertTrue(L2NFT.supportsInterface(type(IERC721).interfaceId));
// Checks if the contract supports the IERC165 interface.
assertTrue(L2Token.supportsInterface(type(IERC165).interfaceId));
assertTrue(L2NFT.supportsInterface(type(IERC165).interfaceId));
}
function test_safeMint_succeeds() external {
......@@ -69,24 +69,24 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
emit Mint(alice, 1);
// Mint the token.
vm.prank(address(L2Bridge));
L2Token.safeMint(alice, 1);
vm.prank(address(L2NFTBridge));
L2NFT.safeMint(alice, 1);
// Token should be owned by alice.
assertEq(L2Token.ownerOf(1), alice);
assertEq(L2NFT.ownerOf(1), alice);
}
function test_safeMint_notBridge_reverts() external {
// Try to mint the token.
vm.expectRevert("OptimismMintableERC721: only bridge can call this function");
vm.prank(address(alice));
L2Token.safeMint(alice, 1);
L2NFT.safeMint(alice, 1);
}
function test_burn_succeeds() external {
// Mint the token first.
vm.prank(address(L2Bridge));
L2Token.safeMint(alice, 1);
vm.prank(address(L2NFTBridge));
L2NFT.safeMint(alice, 1);
// Expect a transfer event.
vm.expectEmit(true, true, true, true);
......@@ -97,37 +97,37 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
emit Burn(alice, 1);
// Burn the token.
vm.prank(address(L2Bridge));
L2Token.burn(alice, 1);
vm.prank(address(L2NFTBridge));
L2NFT.burn(alice, 1);
// Token should be owned by address(0).
vm.expectRevert("ERC721: invalid token ID");
L2Token.ownerOf(1);
L2NFT.ownerOf(1);
}
function test_burn_notBridge_reverts() external {
// Mint the token first.
vm.prank(address(L2Bridge));
L2Token.safeMint(alice, 1);
vm.prank(address(L2NFTBridge));
L2NFT.safeMint(alice, 1);
// Try to burn the token.
vm.expectRevert("OptimismMintableERC721: only bridge can call this function");
vm.prank(address(alice));
L2Token.burn(alice, 1);
L2NFT.burn(alice, 1);
}
function test_tokenURI_succeeds() external {
// Mint the token first.
vm.prank(address(L2Bridge));
L2Token.safeMint(alice, 1);
vm.prank(address(L2NFTBridge));
L2NFT.safeMint(alice, 1);
// Token URI should be correct.
assertEq(
L2Token.tokenURI(1),
L2NFT.tokenURI(1),
string(
abi.encodePacked(
"ethereum:",
Strings.toHexString(uint160(address(L1Token)), 20),
Strings.toHexString(uint160(address(L1NFT)), 20),
"@",
Strings.toString(1),
"/tokenURI?uint256=",
......
......@@ -15,14 +15,14 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {
super.setUp();
// Set up the token pair.
factory = new OptimismMintableERC721Factory(address(L2Bridge), 1);
factory = new OptimismMintableERC721Factory(address(L2NFTBridge), 1);
// Label the addresses for nice traces.
vm.label(address(factory), "OptimismMintableERC721Factory");
}
function test_constructor_succeeds() external {
assertEq(factory.BRIDGE(), address(L2Bridge));
assertEq(factory.BRIDGE(), address(L2NFTBridge));
assertEq(factory.REMOTE_CHAIN_ID(), 1);
}
......@@ -49,7 +49,7 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {
assertEq(created.name(), "L2Token");
assertEq(created.symbol(), "L2T");
assertEq(created.REMOTE_TOKEN(), remote);
assertEq(created.BRIDGE(), address(L2Bridge));
assertEq(created.BRIDGE(), address(L2NFTBridge));
assertEq(created.REMOTE_CHAIN_ID(), 1);
}
......@@ -80,7 +80,7 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {
view
returns (address)
{
bytes memory constructorArgs = abi.encode(address(L2Bridge), 1, _remote, _name, _symbol);
bytes memory constructorArgs = abi.encode(address(L2NFTBridge), 1, _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)));
......
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