Commit 92855691 authored by Mark Tyneway's avatar Mark Tyneway

wip

parent 57aa6104
......@@ -5,6 +5,7 @@ import { ERC721Bridge } from "../universal/ERC721Bridge.sol";
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";
/// @title L1ERC721Bridge
/// @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to
......@@ -15,14 +16,22 @@ contract L1ERC721Bridge is ERC721Bridge, Semver {
/// by ID was deposited for a given L2 token.
mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;
/// @custom:semver 1.1.2
/// @notice Constructs the L1ERC721Bridge contract.
/// @custom:semver 1.3.0
/// @notice Constructs the contract.
constructor()
Semver(1, 3, 0)
ERC721Bridge(Predeploys.L2_ERC721_BRIDGE)
{
initialize({
_messenger: address(0)
});
}
/// @notice Initializes the contract.
/// @param _messenger Address of the CrossDomainMessenger on this network.
/// @param _otherBridge Address of the ERC721 bridge on the other network.
constructor(address _messenger, address _otherBridge)
Semver(1, 1, 2)
ERC721Bridge(_messenger, _otherBridge)
{}
function initialize(address _messenger) public reinitializer(1) {
__ERC721Bridge_init(_messenger);
}
/// @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the
/// recipient on this domain.
......
......@@ -17,14 +17,23 @@ import { Semver } from "../universal/Semver.sol";
/// wait for the one-week challenge period to elapse before their Optimism-native NFT
/// can be refunded on L2.
contract L2ERC721Bridge is ERC721Bridge, Semver {
/// @custom:semver 1.1.1
/// @custom:semver 1.2.0
/// @notice Constructs the L2ERC721Bridge contract.
/// @param _messenger Address of the CrossDomainMessenger on this network.
/// @param _otherBridge Address of the ERC721 bridge on the other network.
constructor(address _messenger, address _otherBridge)
Semver(1, 1, 1)
ERC721Bridge(_messenger, _otherBridge)
{}
constructor(address _otherBridge)
Semver(1, 2, 1)
ERC721Bridge(_otherBridge)
{
initialize({
_messenger: address(0)
});
}
/// @notice Initializes the contract.
/// @param _messenger Address of the CrossDomainMessenger on this network.
function initialize(address _messenger) public reinitializer(1) {
__ERC721Bridge_init(_messenger);
}
/// @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the
/// recipient on this domain.
......
......@@ -3,18 +3,19 @@ pragma solidity 0.8.15;
import { CrossDomainMessenger } from "./CrossDomainMessenger.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
/// @title ERC721Bridge
/// @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges.
abstract contract ERC721Bridge {
abstract contract ERC721Bridge is Initializable {
/// @notice Messenger contract on this domain.
CrossDomainMessenger public immutable MESSENGER;
CrossDomainMessenger public MESSENGER;
/// @notice Address of the bridge on the other network.
address public immutable OTHER_BRIDGE;
/// @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.
uint256[49] private __gap;
uint256[48] private __gap;
/// @notice Emitted when an ERC721 bridge to the other network is initiated.
/// @param localToken Address of the token on this domain.
......@@ -57,16 +58,20 @@ abstract contract ERC721Bridge {
_;
}
/// @param _messenger Address of the CrossDomainMessenger on this network.
/// @notice Constructs the contract.
/// @param _otherBridge Address of the ERC721 bridge on the other network.
constructor(address _messenger, address _otherBridge) {
require(_messenger != address(0), "ERC721Bridge: messenger cannot be address(0)");
constructor(address _otherBridge) {
require(_otherBridge != address(0), "ERC721Bridge: other bridge cannot be address(0)");
MESSENGER = CrossDomainMessenger(_messenger);
OTHER_BRIDGE = _otherBridge;
}
// @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;
}
/// @custom:legacy
/// @notice Legacy getter for messenger contract.
/// @return Messenger contract on this domain.
......
......@@ -499,15 +499,32 @@ contract ERC721Bridge_Initializer is Messenger_Initializer {
super.setUp();
// Deploy the L1ERC721Bridge.
L1Bridge = new L1ERC721Bridge(address(L1Messenger), Predeploys.L2_ERC721_BRIDGE);
L1ERC721Bridge l1BridgeImpl = new L1ERC721Bridge();
Proxy l1BridgeProxy = new Proxy(multisig);
// Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address.
vm.etch(
Predeploys.L2_ERC721_BRIDGE,
address(new L2ERC721Bridge(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(L1Bridge)))
.code
vm.prank(multisig);
l1BridgeProxy.upgradeToAndCall(
address(l1BridgeImpl),
abi.encodeCall(
L1ERC721Bridge.initialize,
address(L1Messenger)
)
);
L1Bridge = L1ERC721Bridge(address(l1BridgeProxy));
// 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
bytes32 IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
bytes32 OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
vm.store(Predeploys.L2_ERC721_BRIDGE, IMPLEMENTATION_KEY, address(l2BridgeProxy));
vm.store(Predeploys.L2_ERC721_BRIDGE, OWNER_KEY, multisig);
// Set up a reference to the L2ERC721Bridge.
L2Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);
......
......@@ -2,12 +2,13 @@
pragma solidity 0.8.15;
// Testing utilities
import { Messenger_Initializer } from "./CommonTest.t.sol";
import { ERC721Bridge_Initializer } from "./CommonTest.t.sol";
// Target contract dependencies
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { L1ERC721Bridge } from "../src/L1/L1ERC721Bridge.sol";
import { OptimismMintableERC721 } from "../src/universal/OptimismMintableERC721.sol";
import { Proxy } from "../src/universal/Proxy.sol";
// Target contract
import { L2ERC721Bridge } from "../src/L2/L2ERC721Bridge.sol";
......@@ -30,7 +31,7 @@ contract TestMintableERC721 is OptimismMintableERC721 {
}
}
contract L2ERC721Bridge_Test is Messenger_Initializer {
contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
TestMintableERC721 internal localToken;
TestERC721 internal remoteToken;
L2ERC721Bridge internal bridge;
......@@ -59,14 +60,9 @@ contract L2ERC721Bridge_Test is Messenger_Initializer {
function setUp() public override {
super.setUp();
// Create necessary contracts.
bridge = new L2ERC721Bridge(address(L2Messenger), otherBridge);
remoteToken = new TestERC721();
localToken = new TestMintableERC721(address(bridge), address(remoteToken));
// Label the bridge so we get nice traces.
vm.label(address(bridge), "L2ERC721Bridge");
// Mint alice a token.
localToken.mint(alice, tokenId);
......
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