Commit d9d3c738 authored by Mark Tyneway's avatar Mark Tyneway

contracts-bedrock: erc721 bridge single impl

Update the ERC721 bridge so that a single implementation
can be used across many different chains.

Still need to double check the storage layout before this
is good, but the tests are passing.

Also need to update all the code that touches the go bindings.
parent 92855691
......@@ -435,14 +435,9 @@ contract Deploy is Deployer {
/// @notice Deploy the L1ERC721Bridge
function deployL1ERC721Bridge() broadcast() public returns (address) {
address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy");
L1ERC721Bridge bridge = new L1ERC721Bridge({
_messenger: l1CrossDomainMessengerProxy,
_otherBridge: Predeploys.L2_ERC721_BRIDGE
});
L1ERC721Bridge bridge = new L1ERC721Bridge();
require(address(bridge.MESSENGER()) == l1CrossDomainMessengerProxy);
require(address(bridge.MESSENGER()) == address(0));
require(bridge.OTHER_BRIDGE() == Predeploys.L2_ERC721_BRIDGE);
save("L1ERC721Bridge", address(bridge));
......@@ -574,9 +569,13 @@ contract Deploy is Deployer {
address l1ERC721Bridge = mustGetAddress("L1ERC721Bridge");
address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy");
proxyAdmin.upgrade({
proxyAdmin.upgradeAndCall({
_proxy: payable(l1ERC721BridgeProxy),
_implementation: l1ERC721Bridge
_implementation: l1ERC721Bridge,
_data: abi.encodeCall(
L1ERC721Bridge.initialize,
(CrossDomainMessenger(l1CrossDomainMessengerProxy))
)
});
L1ERC721Bridge bridge = L1ERC721Bridge(l1ERC721BridgeProxy);
......
......@@ -6,6 +6,7 @@ import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import { L2ERC721Bridge } from "../L2/L2ERC721Bridge.sol";
import { Semver } from "../universal/Semver.sol";
import { Predeploys } from "../libraries/Predeploys.sol";
import { CrossDomainMessenger } from "../universal/CrossDomainMessenger.sol";
/// @title L1ERC721Bridge
/// @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to
......@@ -23,13 +24,13 @@ contract L1ERC721Bridge is ERC721Bridge, Semver {
ERC721Bridge(Predeploys.L2_ERC721_BRIDGE)
{
initialize({
_messenger: address(0)
_messenger: CrossDomainMessenger(address(0))
});
}
/// @notice Initializes the contract.
/// @param _messenger Address of the CrossDomainMessenger on this network.
function initialize(address _messenger) public reinitializer(1) {
function initialize(CrossDomainMessenger _messenger) public reinitializer(1) {
__ERC721Bridge_init(_messenger);
}
......
......@@ -5,6 +5,7 @@ import { ERC721Bridge } from "../universal/ERC721Bridge.sol";
import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import { L1ERC721Bridge } from "../L1/L1ERC721Bridge.sol";
import { IOptimismMintableERC721 } from "../universal/IOptimismMintableERC721.sol";
import { CrossDomainMessenger } from "../universal/CrossDomainMessenger.sol";
import { Semver } from "../universal/Semver.sol";
/// @title L2ERC721Bridge
......@@ -25,13 +26,13 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
ERC721Bridge(_otherBridge)
{
initialize({
_messenger: address(0)
_messenger: CrossDomainMessenger(address(0))
});
}
/// @notice Initializes the contract.
/// @param _messenger Address of the CrossDomainMessenger on this network.
function initialize(address _messenger) public reinitializer(1) {
function initialize(CrossDomainMessenger _messenger) public reinitializer(1) {
__ERC721Bridge_init(_messenger);
}
......
......@@ -68,7 +68,6 @@ abstract contract ERC721Bridge is Initializable {
// @notice Initializes the contract.
/// @param _messenger Address of the CrossDomainMessenger on this network.
function __ERC721Bridge_init(CrossDomainMessenger _messenger) internal onlyInitializing {
require(address(_messenger) != address(0), "ERC721Bridge: messenger cannot be address(0)");
MESSENGER = _messenger;
}
......
......@@ -29,6 +29,7 @@ import { ResolvedDelegateProxy } from "../src/legacy/ResolvedDelegateProxy.sol";
import { AddressManager } from "../src/legacy/AddressManager.sol";
import { L1ChugSplashProxy } from "../src/legacy/L1ChugSplashProxy.sol";
import { IL1ChugSplashDeployer } from "../src/legacy/L1ChugSplashProxy.sol";
import { CrossDomainMessenger } from "../src/universal/CrossDomainMessenger.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { LegacyMintableERC20 } from "../src/legacy/LegacyMintableERC20.sol";
import { SystemConfig } from "../src/L1/SystemConfig.sol";
......@@ -507,7 +508,7 @@ contract ERC721Bridge_Initializer is Messenger_Initializer {
address(l1BridgeImpl),
abi.encodeCall(
L1ERC721Bridge.initialize,
address(L1Messenger)
(CrossDomainMessenger(L1Messenger))
)
);
......@@ -516,14 +517,17 @@ contract ERC721Bridge_Initializer is Messenger_Initializer {
// Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address.
L2ERC721Bridge l2BridgeImpl = new L2ERC721Bridge(address(L1Bridge));
Proxy l2BridgeProxy = new Proxy(multisig);
vm.etch(Predeploys.L2_ERC721_BRIDGE, l2BridgeProxy.code);
// set the storage slot for admin and implementation
vm.etch(Predeploys.L2_ERC721_BRIDGE, address(l2BridgeProxy).code);
bytes32 IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
// set the storage slot for admin
bytes32 OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
vm.store(Predeploys.L2_ERC721_BRIDGE, OWNER_KEY, bytes32(uint256(uint160(multisig))));
vm.store(Predeploys.L2_ERC721_BRIDGE, IMPLEMENTATION_KEY, address(l2BridgeProxy));
vm.store(Predeploys.L2_ERC721_BRIDGE, OWNER_KEY, multisig);
vm.prank(multisig);
Proxy(payable(Predeploys.L2_ERC721_BRIDGE)).upgradeToAndCall(
address(l2BridgeImpl),
abi.encodeCall(L2ERC721Bridge.initialize, (L2Messenger))
);
// Set up a reference to the L2ERC721Bridge.
L2Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);
......
......@@ -2,11 +2,12 @@
pragma solidity 0.8.15;
// Testing utilities
import { Messenger_Initializer } from "./CommonTest.t.sol";
import { ERC721Bridge_Initializer } from "./CommonTest.t.sol";
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
// Target contract dependencies
import { L2ERC721Bridge } from "../src/L2/L2ERC721Bridge.sol";
import { Predeploys } from "../src/libraries/Predeploys.sol";
// Target contract
import { L1ERC721Bridge } from "../src/L1/L1ERC721Bridge.sol";
......@@ -20,11 +21,9 @@ contract TestERC721 is ERC721 {
}
}
contract L1ERC721Bridge_Test is Messenger_Initializer {
contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
TestERC721 internal localToken;
TestERC721 internal remoteToken;
L1ERC721Bridge internal bridge;
address internal constant otherBridge = address(0x3456);
uint256 internal constant tokenId = 1;
event ERC721BridgeInitiated(
......@@ -49,28 +48,23 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
function setUp() public override {
super.setUp();
// Create necessary contracts.
bridge = new L1ERC721Bridge(address(L1Messenger), otherBridge);
localToken = new TestERC721();
remoteToken = new TestERC721();
// Label the bridge so we get nice traces.
vm.label(address(bridge), "L1ERC721Bridge");
// Mint alice a token.
localToken.mint(alice, tokenId);
// Approve the bridge to transfer the token.
vm.prank(alice);
localToken.approve(address(bridge), tokenId);
localToken.approve(address(L1Bridge), tokenId);
}
/// @dev Tests that the constructor sets the correct values.
function test_constructor_succeeds() public {
assertEq(address(bridge.MESSENGER()), address(L1Messenger));
assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);
assertEq(address(bridge.messenger()), address(L1Messenger));
assertEq(address(bridge.otherBridge()), otherBridge);
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);
}
/// @dev Tests that the ERC721 can be bridged successfully.
......@@ -81,7 +75,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
abi.encodeCall(
L1Messenger.sendMessage,
(
address(otherBridge),
address(L2Bridge),
abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721,
(
......@@ -111,11 +105,11 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
// Bridge the token.
vm.prank(alice);
bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L1Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is locked in the bridge.
assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);
assertEq(localToken.ownerOf(tokenId), address(bridge));
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), true);
assertEq(localToken.ownerOf(tokenId), address(L1Bridge));
}
/// @dev Tests that the ERC721 bridge reverts for non externally owned accounts.
......@@ -124,10 +118,10 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
vm.etch(alice, hex"01");
vm.prank(alice);
vm.expectRevert("ERC721Bridge: account is not externally owned");
bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L1Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -136,10 +130,10 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert();
bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678");
L1Bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -148,10 +142,10 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)");
bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678");
L1Bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -160,10 +154,10 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("ERC721: transfer from incorrect owner");
bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L1Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -176,7 +170,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
abi.encodeCall(
L1Messenger.sendMessage,
(
address(otherBridge),
address(Predeploys.L2_ERC721_BRIDGE),
abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721,
(address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678")
......@@ -199,7 +193,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
// Bridge the token.
vm.prank(alice);
bridge.bridgeERC721To(
L1Bridge.bridgeERC721To(
address(localToken),
address(remoteToken),
bob,
......@@ -209,8 +203,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
);
// Token is locked in the bridge.
assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);
assertEq(localToken.ownerOf(tokenId), address(bridge));
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), true);
assertEq(localToken.ownerOf(tokenId), address(L1Bridge));
}
/// @dev Tests that the ERC721 bridge reverts for non externally owned accounts
......@@ -219,10 +213,10 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert();
bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex"5678");
L1Bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -232,10 +226,10 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)");
bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678");
L1Bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -245,7 +239,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("ERC721: transfer from incorrect owner");
bridge.bridgeERC721To(
L1Bridge.bridgeERC721To(
address(localToken),
address(remoteToken),
bob,
......@@ -255,7 +249,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
);
// Token is not locked in the bridge.
assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -263,7 +257,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
function test_finalizeBridgeERC721_succeeds() external {
// Bridge the token.
vm.prank(alice);
bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L1Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
......@@ -280,10 +274,10 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
vm.mockCall(
address(L1Messenger),
abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),
abi.encode(otherBridge)
abi.encode(Predeploys.L2_ERC721_BRIDGE)
);
vm.prank(address(L1Messenger));
bridge.finalizeBridgeERC721(
L1Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
......@@ -293,7 +287,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
);
// Token is not locked in the bridge.
assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(L1Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice);
}
......@@ -303,7 +297,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
// Finalize a withdrawal.
vm.prank(alice);
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
bridge.finalizeBridgeERC721(
L1Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
......@@ -324,7 +318,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
);
vm.prank(address(L1Messenger));
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
bridge.finalizeBridgeERC721(
L1Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
......@@ -341,12 +335,12 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
vm.mockCall(
address(L1Messenger),
abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),
abi.encode(otherBridge)
abi.encode(Predeploys.L2_ERC721_BRIDGE)
);
vm.prank(address(L1Messenger));
vm.expectRevert("L1ERC721Bridge: local token cannot be self");
bridge.finalizeBridgeERC721(
address(bridge),
L1Bridge.finalizeBridgeERC721(
address(L1Bridge),
address(remoteToken),
alice,
alice,
......@@ -362,11 +356,11 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
vm.mockCall(
address(L1Messenger),
abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),
abi.encode(otherBridge)
abi.encode(Predeploys.L2_ERC721_BRIDGE)
);
vm.prank(address(L1Messenger));
vm.expectRevert("L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge");
bridge.finalizeBridgeERC721(
L1Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
......
......@@ -34,8 +34,6 @@ contract TestMintableERC721 is OptimismMintableERC721 {
contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
TestMintableERC721 internal localToken;
TestERC721 internal remoteToken;
L2ERC721Bridge internal bridge;
address internal constant otherBridge = address(0x3456);
uint256 internal constant tokenId = 1;
event ERC721BridgeInitiated(
......@@ -61,22 +59,22 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
super.setUp();
remoteToken = new TestERC721();
localToken = new TestMintableERC721(address(bridge), address(remoteToken));
localToken = new TestMintableERC721(address(L2Bridge), address(remoteToken));
// Mint alice a token.
localToken.mint(alice, tokenId);
// Approve the bridge to transfer the token.
vm.prank(alice);
localToken.approve(address(bridge), tokenId);
localToken.approve(address(L2Bridge), tokenId);
}
/// @dev Tests that the constructor sets the correct variables.
function test_constructor_succeeds() public {
assertEq(address(bridge.MESSENGER()), address(L2Messenger));
assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);
assertEq(address(bridge.messenger()), address(L2Messenger));
assertEq(address(bridge.otherBridge()), otherBridge);
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));
}
/// @dev Tests that `bridgeERC721` correctly bridges a token and
......@@ -88,7 +86,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encodeCall(
L2Messenger.sendMessage,
(
address(otherBridge),
address(L1Bridge),
abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721,
(
......@@ -118,7 +116,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L2Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is burned.
vm.expectRevert("ERC721: invalid token ID");
......@@ -131,7 +129,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.etch(alice, hex"01");
vm.prank(alice);
vm.expectRevert("ERC721Bridge: account is not externally owned");
bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L2Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -142,7 +140,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert();
bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678");
L2Bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -153,7 +151,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)");
bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678");
L2Bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -164,7 +162,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner");
bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L2Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -179,7 +177,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
abi.encodeCall(
L2Messenger.sendMessage,
(
address(otherBridge),
address(L1Bridge),
abi.encodeCall(
L1ERC721Bridge.finalizeBridgeERC721,
(address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678")
......@@ -202,7 +200,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
bridge.bridgeERC721To(
L2Bridge.bridgeERC721To(
address(localToken),
address(remoteToken),
bob,
......@@ -221,7 +219,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert();
bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex"5678");
L2Bridge.bridgeERC721To(address(0), address(L1Bridge), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -232,7 +230,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(alice);
vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)");
bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678");
L2Bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
......@@ -243,7 +241,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner");
bridge.bridgeERC721To(
L2Bridge.bridgeERC721To(
address(localToken),
address(remoteToken),
bob,
......@@ -260,7 +258,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_finalizeBridgeERC721_succeeds() external {
// Bridge the token.
vm.prank(alice);
bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
L2Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
......@@ -277,10 +275,10 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(otherBridge)
abi.encode(L1Bridge)
);
vm.prank(address(L2Messenger));
bridge.finalizeBridgeERC721(
L2Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
......@@ -301,18 +299,18 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the non-compliant token.
vm.prank(alice);
bridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex"5678");
L2Bridge.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(otherBridge)
abi.encode(L1Bridge)
);
vm.prank(address(L2Messenger));
vm.expectRevert("L2ERC721Bridge: local token interface is not compliant");
bridge.finalizeBridgeERC721(
L2Bridge.finalizeBridgeERC721(
address(address(nonCompliantToken)),
address(address(0x01)),
alice,
......@@ -327,7 +325,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");
bridge.finalizeBridgeERC721(
L2Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
......@@ -347,7 +345,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
);
vm.prank(address(L2Messenger));
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
bridge.finalizeBridgeERC721(
L2Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
......@@ -364,12 +362,12 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(otherBridge)
abi.encode(address(L1Bridge))
);
vm.prank(address(L2Messenger));
vm.expectRevert("L2ERC721Bridge: local token cannot be self");
bridge.finalizeBridgeERC721(
address(bridge),
L2Bridge.finalizeBridgeERC721(
address(L2Bridge),
address(remoteToken),
alice,
alice,
......@@ -384,11 +382,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(otherBridge)
abi.encode(address(L1Bridge))
);
vm.prank(address(L2Messenger));
vm.expectRevert("ERC721: token already minted");
bridge.finalizeBridgeERC721(
L2Bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
......
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