Skip to content

Commit

Permalink
Merge branch 'main' into deniallugo-use-chain-admin-for-bridgehub
Browse files Browse the repository at this point in the history
  • Loading branch information
vladbochok authored Sep 12, 2024
2 parents 8f3cf75 + 73b20c4 commit 58cad45
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 18 deletions.
2 changes: 1 addition & 1 deletion l1-contracts/contracts/bridgehub/Bridgehub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
}

/// @notice token can be any contract with the appropriate interface/functionality
function addToken(address _token) external onlyOwner {
function addToken(address _token) external onlyOwnerOrAdmin {
require(!tokenIsRegistered[_token], "Bridgehub: token already registered");
tokenIsRegistered[_token] = true;
}
Expand Down
54 changes: 42 additions & 12 deletions l1-contracts/deploy-scripts/DeployL2Contracts.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,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 @@ -57,21 +65,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 @@ -80,15 +96,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/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json"
Expand All @@ -100,9 +116,16 @@ contract DeployL2Script is Script {
"/../l2-contracts/artifacts-zk/contracts/bridge/L2StandardERC20.sol/L2StandardERC20.json"
);

contracts.l2SharedBridgeBytecode = Utils.readHardhatBytecode(
"/../l2-contracts/artifacts-zk/contracts/bridge/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/artifacts-zk/contracts/bridge/L2SharedBridge.sol/L2SharedBridge.json"
);
}

contracts.l2SharedBridgeProxyBytecode = Utils.readHardhatBytecode(
"/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"
);
Expand Down Expand Up @@ -183,13 +206,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
161 changes: 161 additions & 0 deletions l1-contracts/deploy-scripts/dev/SetupLegacyBridge.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// 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);
vm.broadcast();
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"
);
tokenBeaconBytecodeHash = L2ContractHelper.hashL2Bytecode(beaconProxy);

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

(tokenBeaconAddress, ) = calculateL2Create2Address(
config.l2SharedBridgeAddress,
upgradableBeacon,
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,12 @@ contract ExperimentalBridgeTest is Test {
}

function test_addToken_cannotBeCalledByRandomAddress(address randomAddress, address randomCaller) public {
if (randomCaller != bridgeOwner) {
vm.prank(randomCaller);
vm.expectRevert(bytes("Ownable: caller is not the owner"));
bridgeHub.addToken(randomAddress);
}
vm.assume(randomAddress != bridgeOwner);
vm.assume(randomAddress != bridgeHub.admin());

vm.prank(randomCaller);
vm.expectRevert(bytes("Bridgehub: not owner or admin"));
bridgeHub.addToken(randomAddress);

assertTrue(!bridgeHub.tokenIsRegistered(randomAddress), "This random address is not registered as a token");

Expand Down

0 comments on commit 58cad45

Please sign in to comment.