Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
StanislavBreadless committed May 10, 2024
1 parent 5fa15a8 commit f47da2a
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,8 @@ interface IStateTransitionManager {
uint256 _oldProtocolVersion,
Diamond.DiamondCutData calldata _diamondCut
) external;

function registerSyncLayer(uint256 _newSyncLayerChainId, bool _isWhitelisted) external;

function registerCounterpart(uint256 _chainId, address _counterPart) external;
}
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,12 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own
// TODO: emit event
}

function registerCounterpart(uint256 _chainId, address _counterPart) external onlyOwner {
require(_counterPart != address(0), "STM: counter part zero");

stmCounterParts[_chainId] = _counterPart;
}

function finalizeMigrationToSyncLayer(
uint256 _chainId,
address _baseToken,
Expand Down
3 changes: 2 additions & 1 deletion l1-contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
"token-migration": "ts-node scripts/token-migration.ts",
"setup-legacy-bridge-era": "ts-node scripts/setup-legacy-bridge-era.ts",
"upgrade-consistency-checker": "ts-node scripts/upgrade-consistency-checker.ts",
"governance-accept-ownership": "ts-node scripts/governance-accept-ownership.ts"
"governance-accept-ownership": "ts-node scripts/governance-accept-ownership.ts",
"prepare-sync-layer": "ts-node scripts/prepare-sync-layer.ts"
},
"dependencies": {
"@matterlabs/hardhat-zksync-deploy": "0.6.5",
Expand Down
20 changes: 17 additions & 3 deletions l1-contracts/scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { Command } from "commander";
import { Wallet, ethers } from "ethers";
import { Deployer } from "../src.ts/deploy";
import { formatUnits, parseUnits } from "ethers/lib/utils";
import { web3Provider, GAS_MULTIPLIER } from "./utils";
import { web3Provider, GAS_MULTIPLIER, web3Url } from "./utils";
import { deployedAddressesFromEnv } from "../src.ts/deploy-utils";
import { initialBridgehubDeployment } from "../src.ts/deploy-process";
import { ethTestConfig } from "../src.ts/utils";
import { Wallet as ZkWallet, Provider as ZkProvider } from 'zksync-ethers';

const provider = web3Provider();

Expand All @@ -27,12 +28,25 @@ async function main() {
.option("--diamond-upgrade-init <version>")
.option("--only-verifier")
.action(async (cmd) => {
const deployWallet = cmd.privateKey
let deployWallet: ethers.Wallet | ZkWallet;

if (process.env.CONTRACTS_BASE_NETWORK_ZKSYNC === "true") {
const provider = new ZkProvider(web3Url());
deployWallet = cmd.privateKey
? new ZkWallet(cmd.privateKey, provider)
: ZkWallet.fromMnemonic(
process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic,
"m/44'/60'/0'/0/1"
).connect(provider);
} else {
deployWallet = cmd.privateKey
? new Wallet(cmd.privateKey, provider)
: Wallet.fromMnemonic(
process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic,
"m/44'/60'/0'/0/1"
).connect(provider);
}

console.log(`Using deployer wallet: ${deployWallet.address}`);

const ownerAddress = cmd.ownerAddress ? cmd.ownerAddress : deployWallet.address;
Expand All @@ -55,7 +69,7 @@ async function main() {
verbose: true,
});

if (deployer.zkMode) {
if (deployer.isZkMode()) {
console.log("Deploying on a zkSync network!");
}

Expand Down
165 changes: 165 additions & 0 deletions l1-contracts/scripts/prepare-sync-layer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// hardhat import should be the first import in the file
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import * as hardhat from "hardhat";
import { Command } from "commander";
import { Wallet, ethers } from "ethers";
import { Deployer } from "../src.ts/deploy";
import { formatUnits, parseUnits } from "ethers/lib/utils";
import { web3Provider, GAS_MULTIPLIER, web3Url } from "./utils";
import { deployedAddressesFromEnv } from "../src.ts/deploy-utils";
import { initialBridgehubDeployment } from "../src.ts/deploy-process";
import { ethTestConfig, getAddressFromEnv, getNumberFromEnv } from "../src.ts/utils";

import { Wallet as ZkWallet, Provider as ZkProvider } from 'zksync-ethers';

const provider = web3Provider();

async function main() {
const program = new Command();

program.version("0.1.0").name("deploy").description("deploy L1 contracts");

program
.command('deploy-sync-layer-contracts')
.option("--private-key <private-key>")
.option("--chain-id <chain-id>")
.option("--gas-price <gas-price>")
.option("--owner-address <owner-address>")
.option("--create2-salt <create2-salt>")
.option("--diamond-upgrade-init <version>")
.option("--only-verifier")
.action(async (cmd) => {
if(process.env.CONTRACTS_BASE_NETWORK_ZKSYNC !== "true") {
throw new Error("This script is only for zkSync network");
}

let deployWallet: ethers.Wallet | ZkWallet;

// if (process.env.CONTRACTS_BASE_NETWORK_ZKSYNC === "true") {
const provider = new ZkProvider(process.env.API_WEB3_JSON_RPC_HTTP_URL);
deployWallet = cmd.privateKey
? new ZkWallet(cmd.privateKey, provider)
: ZkWallet.fromMnemonic(
process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic,
"m/44'/60'/0'/0/1"
).connect(provider);
// } else {
// deployWallet = cmd.privateKey
// ? new Wallet(cmd.privateKey, provider)
// : Wallet.fromMnemonic(
// process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic,
// "m/44'/60'/0'/0/1"
// ).connect(provider);
// }

console.log(`Using deployer wallet: ${deployWallet.address}`);

const ownerAddress = cmd.ownerAddress ? cmd.ownerAddress : deployWallet.address;
console.log(`Using owner address: ${ownerAddress}`);

const gasPrice = cmd.gasPrice
? parseUnits(cmd.gasPrice, "gwei")
: (await provider.getGasPrice()).mul(GAS_MULTIPLIER);
console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`);

const nonce = cmd.nonce ? parseInt(cmd.nonce) : await deployWallet.getTransactionCount();
console.log(`Using nonce: ${nonce}`);

const create2Salt = cmd.create2Salt ? cmd.create2Salt : ethers.utils.hexlify(ethers.utils.randomBytes(32));

const deployer = new Deployer({
deployWallet,
addresses: deployedAddressesFromEnv(),
ownerAddress,
verbose: true,
});

if (deployer.isZkMode()) {
console.log("Deploying on a zkSync network!");
}

await deployer.updateCreate2FactoryZkMode();
await deployer.updateBlobVersionedHashRetrieverZkMode();

await deployer.deployMulticall3(create2Salt, { gasPrice });
await deployer.deployDefaultUpgrade(create2Salt, { gasPrice });
await deployer.deployGenesisUpgrade(create2Salt, { gasPrice });

await deployer.deployGovernance(create2Salt, { gasPrice });
await deployer.deployVerifier(create2Salt, { gasPrice });

await deployer.deployTransparentProxyAdmin(create2Salt, { gasPrice });

// SyncLayer does not need to have all the same contracts as on L1.
// We only need validator timelock as well as the STM.
await deployer.deployValidatorTimelock(create2Salt, { gasPrice });

// On L2 there is no bridgebub.
deployer.addresses.Bridgehub.BridgehubProxy = ethers.constants.AddressZero;

await deployer.deployStateTransitionDiamondFacets(create2Salt, gasPrice);
await deployer.deployStateTransitionManagerImplementation(create2Salt, { gasPrice });
await deployer.deployStateTransitionManagerProxy(create2Salt, { gasPrice });
});

program
.command('register-sync-layer')
.option("--private-key <private-key>")
.option("--chain-id <chain-id>")
.option("--gas-price <gas-price>")
.option("--owner-address <owner-address>")
.option("--create2-salt <create2-salt>")
.option("--diamond-upgrade-init <version>")
.option("--only-verifier")
.action(async (cmd) => {
// Now, all the operations are done on L1
const deployWallet = cmd.privateKey
? new Wallet(cmd.privateKey, provider)
: Wallet.fromMnemonic(
process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic,
"m/44'/60'/0'/0/1"
).connect(provider);

const ownerAddress = cmd.ownerAddress ? cmd.ownerAddress : deployWallet.address;
console.log(`Using owner address: ${ownerAddress}`);


const stmOnSyncLayer = getAddressFromEnv('SYNC_LAYER_STATE_TRANSITION_PROXY_ADDR');
const chainId = getNumberFromEnv('CHAIN_ETH_ZKSYNC_NETWORK_ID');

console.log(`STM on SyncLayer: ${stmOnSyncLayer}`);
console.log(`SyncLayer chain Id: ${chainId}`);

const deployer = new Deployer({
deployWallet,
addresses: deployedAddressesFromEnv(),
ownerAddress,
verbose: true,
});

const l1STM = deployer.stateTransitionManagerContract(deployWallet);
console.log(deployer.addresses.StateTransition.StateTransitionProxy);
// this script only works when owner is the deployer
console.log(`Registering SyncLayer chain id on the STM`);
console.log(await l1STM.owner());
return;
const registerChainIdTx = await l1STM.registerSyncLayer(chainId, true);
console.log(`Transaction hash: ${registerChainIdTx.hash}`);
await registerChainIdTx.wait();

console.log(`Registering STM counter part on the SyncLayer`);
const registerCounterpartTx = await l1STM.registerCounterpart(chainId, stmOnSyncLayer);
console.log(`Transaction hash: ${registerCounterpartTx.hash}`);
await registerCounterpartTx.wait();
console.log(`SyncLayer registration completed`);
});

await program.parseAsync(process.argv);
}

main()
.then(() => process.exit(0))
.catch((err) => {
console.error("Error:", err);
process.exit(1);
});
4 changes: 2 additions & 2 deletions l1-contracts/src.ts/deploy-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export async function initialBridgehubDeployment(

// Create2 factory already deployed on the public networks, only deploy it on local node
if (isCurrentNetworkLocal()) {
if (!deployer.zkMode) {
if (!deployer.isZkMode()) {
await deployer.deployCreate2Factory({ gasPrice, nonce });
nonce++;
} else {
Expand Down Expand Up @@ -64,7 +64,7 @@ export async function initialBridgehubDeployment(
await deployer.deployGovernance(create2Salt, { gasPrice, nonce });
await deployer.deployTransparentProxyAdmin(create2Salt, { gasPrice });
await deployer.deployBridgehubContract(create2Salt, gasPrice);
if (deployer.zkMode) {
if (deployer.isZkMode()) {
await deployer.updateBlobVersionedHashRetrieverZkMode();
} else {
await deployer.deployBlobVersionedHashRetriever(create2Salt, { gasPrice });
Expand Down
16 changes: 7 additions & 9 deletions l1-contracts/src.ts/deploy-utils-zk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ethersWalletToZkWallet } from "./utils";
export const BUILT_IN_ZKSYNC_CREATE2_FACTORY = "0x0000000000000000000000000000000000010000";

export async function deployViaCreate2(
deployWallet: ethers.Wallet,
deployWallet: ZkWallet,
contractName: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
args: any[],
Expand All @@ -24,7 +24,7 @@ export async function deployViaCreate2(
}

export async function deployBytecodeViaCreate2(
deployWallet: ethers.Wallet,
deployWallet: ZkWallet,
contractName: string,
create2Salt: string,
ethTxOptions: ethers.providers.TransactionRequest,
Expand All @@ -33,8 +33,6 @@ export async function deployBytecodeViaCreate2(
): Promise<[string, string]> {
// [address, txHash]

const zksyncWallet = new ZkWallet(deployWallet.privateKey, new Provider(web3Url()));

const log = (msg: string) => {
if (verbose) {
console.log(msg);
Expand All @@ -43,7 +41,7 @@ export async function deployBytecodeViaCreate2(
log(`Deploying ${contractName}`);

// @ts-ignore
const zkDeployer = ZkDeployer.fromEthWallet(hardhat, deployWallet);
const zkDeployer = new ZkDeployer(hardhat, deployWallet);
const artifact = await zkDeployer.loadArtifact(contractName);
const factoryDeps = await zkDeployer.extractFactoryDeps(artifact);

Expand All @@ -52,18 +50,18 @@ export async function deployBytecodeViaCreate2(
const encodedArgs = iface.encodeDeploy(args);

// The CREATE2Factory has the same interface as the contract deployer
const create2Factory = IL2ContractDeployerFactory.connect(BUILT_IN_ZKSYNC_CREATE2_FACTORY, zksyncWallet);
const create2Factory = IL2ContractDeployerFactory.connect(BUILT_IN_ZKSYNC_CREATE2_FACTORY, deployWallet);
const expectedAddress = zkUtils.create2Address(create2Factory.address, bytecodeHash, create2Salt, encodedArgs);

const deployedBytecodeBefore = await zksyncWallet.provider.getCode(expectedAddress);
const deployedBytecodeBefore = await deployWallet.provider.getCode(expectedAddress);
if (ethers.utils.hexDataLength(deployedBytecodeBefore) > 0) {
log(`Contract ${contractName} already deployed`);
return [expectedAddress, ethers.constants.HashZero];
}

const encodedTx = create2Factory.interface.encodeFunctionData("create2", [create2Salt, bytecodeHash, encodedArgs]);

const tx = await zksyncWallet.sendTransaction({
const tx = await deployWallet.sendTransaction({
data: encodedTx,
to: create2Factory.address,
...ethTxOptions,
Expand All @@ -76,7 +74,7 @@ export async function deployBytecodeViaCreate2(
const gasUsed = receipt.gasUsed;
log(`${contractName} deployed, gasUsed: ${gasUsed.toString()}`);

const deployedBytecodeAfter = await zksyncWallet.provider.getCode(expectedAddress);
const deployedBytecodeAfter = await deployWallet.provider.getCode(expectedAddress);
if (ethers.utils.hexDataLength(deployedBytecodeAfter) == 0) {
throw new Error(`Failed to deploy ${contractName} bytecode via create2 factory`);
}
Expand Down
Loading

0 comments on commit f47da2a

Please sign in to comment.