Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: correct local bridge testing #440

Merged
merged 14 commits into from
May 2, 2024
33 changes: 33 additions & 0 deletions l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.20;

import {L2SharedBridge} from "../bridge/L2SharedBridge.sol";
import {L2StandardERC20} from "../bridge/L2StandardERC20.sol";
import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";

/// @author Matter Labs
/// @notice The implementation of the shared bridge that allows setting legacy bridge. Must only be used in local testing environments.
contract DevL2SharedBridge is L2SharedBridge {
constructor(uint256 _eraChainId) L2SharedBridge(_eraChainId) {}

function initializeDevBridge(
address _l1SharedBridge,
address _l1Bridge,
bytes32 _l2TokenProxyBytecodeHash,
address _aliasedOwner
) external reinitializer(2) {
l1SharedBridge = _l1SharedBridge;

address l2StandardToken = address(new L2StandardERC20{salt: bytes32(0)}());
l2TokenBeacon = new UpgradeableBeacon{salt: bytes32(0)}(l2StandardToken);
l2TokenProxyBytecodeHash = _l2TokenProxyBytecodeHash;
l2TokenBeacon.transferOwnership(_aliasedOwner);

// Unfortunately the `l1Bridge` is not an internal variable in the parent contract.
// To keep the changes to the production code minimal, we'll just manually set the variable here.
assembly {
sstore(4, _l1Bridge)
}
}
}
51 changes: 34 additions & 17 deletions l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { GAS_MULTIPLIER } from "../../l1-contracts/scripts/utils";
import * as hre from "hardhat";

export const L2_SHARED_BRIDGE_ABI = hre.artifacts.readArtifactSync("L2SharedBridge").abi;
export const L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE = hre.artifacts.readArtifactSync("L2SharedBridge").bytecode;
export const L2_STANDARD_TOKEN_PROXY_BYTECODE = hre.artifacts.readArtifactSync("BeaconProxy").bytecode;

export async function publishL2SharedBridgeDependencyBytecodesOnL2(
Expand Down Expand Up @@ -60,18 +59,23 @@ export async function deploySharedBridgeImplOnL2ThroughL1(
console.log("Deploying L2SharedBridge Implementation");
}
const eraChainId = process.env.CONTRACTS_ERA_CHAIN_ID;
if (!L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE) {
throw new Error("L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE not found");

const l2SharedBridgeImplementationBytecode = localLegacyBridgeTesting
? hre.artifacts.readArtifactSync("DevL2SharedBridge").bytecode
: hre.artifacts.readArtifactSync("L2SharedBridge").bytecode;

if (!l2SharedBridgeImplementationBytecode) {
throw new Error("l2SharedBridgeImplementationBytecode not found");
}
if (deployer.verbose) {
console.log("L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE loaded");
console.log("l2SharedBridgeImplementationBytecode loaded");

console.log("Computing L2SharedBridge Implementation Address");
}
const l2SharedBridgeImplAddress = computeL2Create2Address(
deployer.deployWallet,
L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE,
defaultAbiCoder.encode(["uint256"], [localLegacyBridgeTesting ? 0 : eraChainId]),
l2SharedBridgeImplementationBytecode,
defaultAbiCoder.encode(["uint256"], [eraChainId]),
ethers.constants.HashZero
);
deployer.addresses.Bridges.L2SharedBridgeImplementation = l2SharedBridgeImplAddress;
Expand All @@ -88,8 +92,8 @@ export async function deploySharedBridgeImplOnL2ThroughL1(
const tx2 = await create2DeployFromL1(
chainId,
deployer.deployWallet,
L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE,
defaultAbiCoder.encode(["uint256"], [localLegacyBridgeTesting ? 0 : eraChainId]),
l2SharedBridgeImplementationBytecode,
defaultAbiCoder.encode(["uint256"], [eraChainId]),
ethers.constants.HashZero,
priorityTxMaxGasLimit,
gasPrice,
Expand All @@ -106,21 +110,34 @@ export async function deploySharedBridgeImplOnL2ThroughL1(
export async function deploySharedBridgeProxyOnL2ThroughL1(
deployer: Deployer,
chainId: string,
gasPrice: BigNumberish
gasPrice: BigNumberish,
localLegacyBridgeTesting: boolean = false
) {
const l1SharedBridge = deployer.defaultSharedBridge(deployer.deployWallet);
if (deployer.verbose) {
console.log("Deploying L2SharedBridge Proxy");
}
/// prepare proxyInitializationParams
const l2GovernorAddress = applyL1ToL2Alias(deployer.addresses.Governance);
const l2SharedBridgeInterface = new Interface(hre.artifacts.readArtifactSync("L2SharedBridge").abi);
const proxyInitializationParams = l2SharedBridgeInterface.encodeFunctionData("initialize", [
l1SharedBridge.address,
deployer.addresses.Bridges.ERC20BridgeProxy,
hashL2Bytecode(L2_STANDARD_TOKEN_PROXY_BYTECODE),
l2GovernorAddress,
]);

let proxyInitializationParams;
if (localLegacyBridgeTesting) {
const l2SharedBridgeInterface = new Interface(hre.artifacts.readArtifactSync("DevL2SharedBridge").abi);
proxyInitializationParams = l2SharedBridgeInterface.encodeFunctionData("initializeDevBridge", [
l1SharedBridge.address,
deployer.addresses.Bridges.ERC20BridgeProxy,
hashL2Bytecode(L2_STANDARD_TOKEN_PROXY_BYTECODE),
l2GovernorAddress,
]);
} else {
const l2SharedBridgeInterface = new Interface(hre.artifacts.readArtifactSync("L2SharedBridge").abi);
proxyInitializationParams = l2SharedBridgeInterface.encodeFunctionData("initialize", [
l1SharedBridge.address,
deployer.addresses.Bridges.ERC20BridgeProxy,
hashL2Bytecode(L2_STANDARD_TOKEN_PROXY_BYTECODE),
l2GovernorAddress,
]);
}

/// prepare constructor data
const l2SharedBridgeProxyConstructorData = ethers.utils.arrayify(
Expand Down Expand Up @@ -187,7 +204,7 @@ export async function deploySharedBridgeOnL2ThroughL1(
) {
await publishL2SharedBridgeDependencyBytecodesOnL2(deployer, chainId, gasPrice);
await deploySharedBridgeImplOnL2ThroughL1(deployer, chainId, gasPrice, localLegacyBridgeTesting);
await deploySharedBridgeProxyOnL2ThroughL1(deployer, chainId, gasPrice);
await deploySharedBridgeProxyOnL2ThroughL1(deployer, chainId, gasPrice, localLegacyBridgeTesting);
await initializeChainGovernance(deployer, chainId);
}

Expand Down
Loading