Skip to content

Commit

Permalink
chore: merge main (#790)
Browse files Browse the repository at this point in the history
Signed-off-by: Danil <deniallugo@gmail.com>
Co-authored-by: Danil <deniallugo@gmail.com>
Co-authored-by: Vlad Bochok <41153528+vladbochok@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 10, 2024
1 parent b653ac8 commit cc3b2ac
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 22 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ l1-contracts/script-config/*
l1-contracts/script-out/*
!l1-contracts/script-out/.gitkeep
*.timestamp
l1-contracts/test/foundry/l1/integration/deploy-scripts/script-out/*
l1-contracts/zkout/*
54 changes: 42 additions & 12 deletions l1-contracts/deploy-scripts/DeployL2Contracts.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,20 @@ contract DeployL2Script is Script {
}

function run() public {
deploy(false);
}

function runWithLegacyBridge() public {
deploy(true);
}

function deploy(bool legacyBridge) public {
initializeConfig();
loadContracts();
loadContracts(legacyBridge);

deployFactoryDeps();
deploySharedBridge();
deploySharedBridgeProxy();
deploySharedBridgeProxy(legacyBridge);
initializeChain();
deployForceDeployer();
deployConsensusRegistry();
Expand All @@ -60,21 +68,29 @@ contract DeployL2Script is Script {
saveOutput();
}

function runDeployLegacySharedBridge() public {
deploySharedBridge(true);
}

function runDeploySharedBridge() public {
deploySharedBridge(false);
}

function deploySharedBridge(bool legacyBridge) internal {
initializeConfig();
loadContracts();
loadContracts(legacyBridge);

deployFactoryDeps();
deploySharedBridge();
deploySharedBridgeProxy();
deploySharedBridgeProxy(legacyBridge);
initializeChain();

saveOutput();
}

function runDefaultUpgrader() public {
initializeConfig();
loadContracts();
loadContracts(false);

deployForceDeployer();

Expand All @@ -83,15 +99,15 @@ contract DeployL2Script is Script {

function runDeployConsensusRegistry() public {
initializeConfig();
loadContracts();
loadContracts(false);

deployConsensusRegistry();
deployConsensusRegistryProxy();

saveOutput();
}

function loadContracts() internal {
function loadContracts(bool legacyBridge) internal {
//HACK: Meanwhile we are not integrated foundry zksync we use contracts that has been built using hardhat
contracts.l2StandardErc20FactoryBytecode = Utils.readHardhatBytecode(
"/../l2-contracts/artifacts-zk/@openzeppelin/contracts-v4/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json"
Expand All @@ -103,9 +119,16 @@ contract DeployL2Script is Script {
"/../l2-contracts/artifacts-zk/contracts/bridge/L2StandardERC20.sol/L2StandardERC20.json"
);

contracts.l2SharedBridgeBytecode = Utils.readFoundryBytecode(
"/../l2-contracts/zkout/L2SharedBridge.sol/L2SharedBridge.json"
);
if (legacyBridge) {
contracts.l2SharedBridgeBytecode = Utils.readHardhatBytecode(
"/../l2-contracts/artifacts-zk/contracts/dev-contracts/DevL2SharedBridge.sol/DevL2SharedBridge.json"
);
} else {
contracts.l2SharedBridgeBytecode = Utils.readHardhatBytecode(
"/../l2-contracts/zkout/L2SharedBridge.sol/L2SharedBridge.json"
);
}

contracts.l2SharedBridgeProxyBytecode = Utils.readHardhatBytecode(
"/../l2-contracts/artifacts-zk/@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"
);
Expand Down Expand Up @@ -186,13 +209,20 @@ contract DeployL2Script is Script {
});
}

function deploySharedBridgeProxy() internal {
function deploySharedBridgeProxy(bool legacyBridge) internal {
address l2GovernorAddress = AddressAliasHelper.applyL1ToL2Alias(config.governance);
bytes32 l2StandardErc20BytecodeHash = L2ContractHelper.hashL2Bytecode(contracts.beaconProxy);

string memory functionSignature;

if (legacyBridge) {
functionSignature = "initializeDevBridge(address,address,bytes32,address)";
} else {
functionSignature = "initialize(address,address,bytes32,address)";
}
// solhint-disable-next-line func-named-parameters
bytes memory proxyInitializationParams = abi.encodeWithSignature(
"initialize(address,address,bytes32,address)",
functionSignature,
config.l1SharedBridgeProxy,
config.erc20BridgeProxy,
l2StandardErc20BytecodeHash,
Expand Down
155 changes: 155 additions & 0 deletions l1-contracts/deploy-scripts/dev/SetupLegacyBridge.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import {Script} from "forge-std/Script.sol";
import {stdToml} from "forge-std/StdToml.sol";
import {Utils} from "./../Utils.sol";
import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol";
import {DummyL1ERC20Bridge} from "contracts/dev-contracts/DummyL1ERC20Bridge.sol";
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {L2ContractHelper} from "contracts/common/libraries/L2ContractHelper.sol";

/// This scripts is only for developer
contract SetupLegacyBridge is Script {
using stdToml for string;

Config internal config;
Addresses internal addresses;

struct Config {
uint256 chainId;
address l2SharedBridgeAddress;
bytes32 create2FactorySalt;
}

struct Addresses {
address create2FactoryAddr;
address bridgehub;
address diamondProxy;
address sharedBridgeProxy;
address transparentProxyAdmin;
address erc20BridgeProxy;
address tokenWethAddress;
address erc20BridgeProxyImpl;
address sharedBridgeProxyImpl;
}

function run() public {
initializeConfig();
deploySharedBridgeImplementation();
upgradeImplementation(addresses.sharedBridgeProxy, addresses.sharedBridgeProxyImpl);
deployDummyErc20Bridge();
upgradeImplementation(addresses.erc20BridgeProxy, addresses.erc20BridgeProxyImpl);
setParamsForDummyBridge();
}

function initializeConfig() internal {
string memory root = vm.projectRoot();
string memory path = string.concat(root, "/script-config/setup-legacy-bridge.toml");
string memory toml = vm.readFile(path);

addresses.bridgehub = toml.readAddress("$.bridgehub");
addresses.diamondProxy = toml.readAddress("$.diamond_proxy");
addresses.sharedBridgeProxy = toml.readAddress("$.shared_bridge_proxy");
addresses.transparentProxyAdmin = toml.readAddress("$.transparent_proxy_admin");
addresses.erc20BridgeProxy = toml.readAddress("$.erc20bridge_proxy");
addresses.tokenWethAddress = toml.readAddress("$.token_weth_address");
addresses.create2FactoryAddr = toml.readAddress("$.create2factory_addr");
config.chainId = toml.readUint("$.chain_id");
config.l2SharedBridgeAddress = toml.readAddress("$.l2shared_bridge_address");
config.create2FactorySalt = toml.readBytes32("$.create2factory_salt");
}

// We need to deploy new shared bridge for changing chain id and diamond proxy address
function deploySharedBridgeImplementation() internal {
bytes memory bytecode = abi.encodePacked(
type(L1SharedBridge).creationCode,
// solhint-disable-next-line func-named-parameters
abi.encode(addresses.tokenWethAddress, addresses.bridgehub, config.chainId, addresses.diamondProxy)
);

address contractAddress = deployViaCreate2(bytecode);
addresses.sharedBridgeProxyImpl = contractAddress;
}

function deployDummyErc20Bridge() internal {
bytes memory bytecode = abi.encodePacked(
type(DummyL1ERC20Bridge).creationCode,
// solhint-disable-next-line func-named-parameters
abi.encode(addresses.sharedBridgeProxy)
);
address contractAddress = deployViaCreate2(bytecode);
addresses.erc20BridgeProxyImpl = contractAddress;
}

function upgradeImplementation(address proxy, address implementation) internal {
bytes memory proxyAdminUpgradeData = abi.encodeCall(
ProxyAdmin.upgrade,
(ITransparentUpgradeableProxy(proxy), implementation)
);
ProxyAdmin _proxyAdmin = ProxyAdmin(addresses.transparentProxyAdmin);
address governance = _proxyAdmin.owner();

Utils.executeUpgrade({
_governor: address(governance),
_salt: bytes32(0),
_target: address(addresses.transparentProxyAdmin),
_data: proxyAdminUpgradeData,
_value: 0,
_delay: 0
});
}

function setParamsForDummyBridge() internal {
(address l2TokenBeacon, bytes32 l2TokenBeaconHash) = calculateTokenBeaconAddress();
DummyL1ERC20Bridge bridge = DummyL1ERC20Bridge(addresses.erc20BridgeProxy);
bridge.setValues(config.l2SharedBridgeAddress, l2TokenBeacon, l2TokenBeaconHash);
}

function calculateTokenBeaconAddress()
internal
returns (address tokenBeaconAddress, bytes32 tokenBeaconBytecodeHash)
{
bytes memory l2StandardTokenCode = Utils.readHardhatBytecode(
"/../l2-contracts/artifacts-zk/contracts/bridge/L2StandardERC20.sol/L2StandardERC20.json"
);
(address l2StandardToken, ) = calculateL2Create2Address(
config.l2SharedBridgeAddress,
l2StandardTokenCode,
bytes32(0),
""
);

bytes memory beaconProxy = Utils.readHardhatBytecode(
"/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json"
);

(tokenBeaconAddress, tokenBeaconBytecodeHash) = calculateL2Create2Address(
config.l2SharedBridgeAddress,
beaconProxy,
bytes32(0),
abi.encode(l2StandardToken)
);
}

function calculateL2Create2Address(
address sender,
bytes memory bytecode,
bytes32 create2salt,
bytes memory constructorargs
) internal returns (address create2Address, bytes32 bytecodeHash) {
bytecodeHash = L2ContractHelper.hashL2Bytecode(bytecode);

create2Address = L2ContractHelper.computeCreate2Address(
sender,
create2salt,
bytecodeHash,
keccak256(constructorargs)
);
}

function deployViaCreate2(bytes memory _bytecode) internal returns (address) {
return Utils.deployViaCreate2(_bytecode, config.create2FactorySalt, addresses.create2FactoryAddr);
}
}
3 changes: 2 additions & 1 deletion l1-contracts/test/unit_tests/custom_base_token.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ describe("Custom base token chain and bridge tests", () => {
const revertReason = await getCallRevertReason(
l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, "0x", [])
);
expect(revertReason).contains("MalformedMessage");
console.log(revertReason);
expect(revertReason).contains("L2WithdrawalMessageWrongLength");
});

it("Should revert on finalizing a withdrawal with wrong function selector", async () => {
Expand Down
6 changes: 3 additions & 3 deletions l1-contracts/test/unit_tests/l1_shared_bridge_test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ describe("Shared Bridge tests", () => {
const revertReason = await getCallRevertReason(
l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, "0x", [ethers.constants.HashZero])
);
expect(revertReason).contains("MalformedMessage");
expect(revertReason).contains("L2WithdrawalMessageWrongLength");
});

it("Should revert on finalizing a withdrawal with wrong message length", async () => {
Expand All @@ -145,7 +145,7 @@ describe("Shared Bridge tests", () => {
[ethers.constants.HashZero]
)
);
expect(revertReason).contains("MalformedMessage");
expect(revertReason).contains("L2WithdrawalMessageWrongLength");
});

it("Should revert on finalizing a withdrawal with wrong function selector", async () => {
Expand Down Expand Up @@ -183,7 +183,7 @@ describe("Shared Bridge tests", () => {
const revertReason = await getCallRevertReason(
l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, "0x", [ethers.constants.HashZero])
);
expect(revertReason).contains("MalformedMessage");
expect(revertReason).contains("L2WithdrawalMessageWrongLength");
});

it("Should revert on finalizing a withdrawal with wrong function signature", async () => {
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import {
} from "./utils";
import { packSemver, unpackStringSemVer, addToProtocolVersion } from "../../scripts/utils";

describe.only("L2 upgrade test", function () {
describe("L2 upgrade test", function () {
let proxyExecutor: ExecutorFacet;
let proxyAdmin: AdminFacet;
let proxyGetters: GettersFacet;
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/test/unit_tests/legacy_era_test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ describe("Legacy Era tests", function () {
const revertReason = await getCallRevertReason(
l1ERC20Bridge.connect(randomSigner).finalizeWithdrawal(0, 0, 0, "0x", [ethers.constants.HashZero])
);
expect(revertReason).contains("MalformedMessage");
expect(revertReason).contains("L2WithdrawalMessageWrongLength");
});

it("Should revert on finalizing a withdrawal with wrong function signature", async () => {
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/test/unit_tests/mailbox_test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ describe("Mailbox tests", function () {
)
);

expect(revertReason).contains("MalformedBytecode");
expect(revertReason).contains("LengthIsNotDivisibleBy32");
});

it("Should not accept bytecode of even length in words", async () => {
Expand Down
6 changes: 3 additions & 3 deletions l1-contracts/test/unit_tests/proxy_test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@ describe("Diamond proxy tests", function () {
const proxyAsERC20 = TestnetERC20TokenFactory.connect(proxy.address, proxy.signer);

const revertReason = await getCallRevertReason(proxyAsERC20.transfer(proxyAsERC20.address, 0));
expect(revertReason).contains("InvalidSelector");
expect(revertReason).contains("F");
});

it("check that proxy reject data with no selector", async () => {
const dataWithoutSelector = "0x1122";

const revertReason = await getCallRevertReason(proxy.fallback({ data: dataWithoutSelector }));
expect(revertReason).contains("MalformedCalldata");
expect(revertReason).contains("Ut");
});

it("should freeze the diamond storage", async () => {
Expand Down Expand Up @@ -178,7 +178,7 @@ describe("Diamond proxy tests", function () {
data: executorFacetSelector3 + "0000000000000000000000000000000000000000000000000000000000000000",
})
);
expect(revertReason).contains("FacetIsFrozen");
expect(revertReason).contains("q1");
});

it("should be able to call an unfreezable facet when diamondStorage is frozen", async () => {
Expand Down

0 comments on commit cc3b2ac

Please sign in to comment.