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

feat: new system contracts #537

Merged
merged 25 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions l1-contracts/contracts/bridge/L1NativeTokenVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {ReentrancyGuard} from "../common/ReentrancyGuard.sol";
import {IL1AssetHandler} from "./interfaces/IL1AssetHandler.sol";

import {IL1SharedBridge} from "./interfaces/IL1SharedBridge.sol";
import {ETH_TOKEN_ADDRESS, NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS} from "../common/Config.sol";
import {ETH_TOKEN_ADDRESS} from "../common/Config.sol";
import {L2_NATIVE_TOKEN_VAULT_ADDRESS} from "../common/L2ContractAddresses.sol";

/// @author Matter Labs
/// @custom:security-contact [email protected]
Expand Down Expand Up @@ -238,11 +239,7 @@ contract L1NativeTokenVault is
function getAssetId(address _l1TokenAddress) public view override returns (bytes32) {
return
keccak256(
abi.encode(
block.chainid,
NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS,
bytes32(uint256(uint160(_l1TokenAddress)))
)
abi.encode(block.chainid, L2_NATIVE_TOKEN_VAULT_ADDRESS, bytes32(uint256(uint160(_l1TokenAddress))))
);
}
}
8 changes: 5 additions & 3 deletions l1-contracts/contracts/bridge/L1SharedBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import {L2Message, TxStatus} from "../common/Messaging.sol";
import {UnsafeBytes} from "../common/libraries/UnsafeBytes.sol";
import {ReentrancyGuard} from "../common/ReentrancyGuard.sol";
import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol";
import {NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS, TWO_BRIDGES_MAGIC_VALUE, ETH_TOKEN_ADDRESS} from "../common/Config.sol";
import {TWO_BRIDGES_MAGIC_VALUE, ETH_TOKEN_ADDRESS} from "../common/Config.sol";
import {L2_NATIVE_TOKEN_VAULT_ADDRESS} from "../common/L2ContractAddresses.sol";

import {IBridgehub, L2TransactionRequestTwoBridgesInner, L2TransactionRequestDirect} from "../bridgehub/IBridgehub.sol";
import {L2_BASE_TOKEN_SYSTEM_CONTRACT_ADDR} from "../common/L2ContractAddresses.sol";

Expand Down Expand Up @@ -184,7 +186,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade

/// @dev Used to set the assedAddress for a given assetId.
function setAssetHandlerAddressInitial(bytes32 _additionalData, address _assetHandlerAddress) external {
address sender = msg.sender == address(nativeTokenVault) ? NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS : msg.sender;
address sender = msg.sender == address(nativeTokenVault) ? L2_NATIVE_TOKEN_VAULT_ADDRESS : msg.sender;
bytes32 assetId = keccak256(abi.encode(uint256(block.chainid), sender, _additionalData));
assetHandlerAddress[assetId] = _assetHandlerAddress;
assetDeploymentTracker[assetId] = sender;
Expand Down Expand Up @@ -252,7 +254,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade
function _getAssetProperties(bytes32 _assetId) internal returns (address l1AssetHandler, bytes32 assetId) {
// Check if the passed id is the address and assume NTV for the case
assetId = uint256(_assetId) <= type(uint160).max
? keccak256(abi.encode(block.chainid, NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS, _assetId))
? keccak256(abi.encode(block.chainid, L2_NATIVE_TOKEN_VAULT_ADDRESS, _assetId))
: _assetId;
l1AssetHandler = assetHandlerAddress[_assetId];
// Check if no asset handler is set
Expand Down
12 changes: 8 additions & 4 deletions l1-contracts/contracts/bridgehub/Bridgehub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {IL1SharedBridge} from "../bridge/interfaces/IL1SharedBridge.sol";
import {IStateTransitionManager} from "../state-transition/IStateTransitionManager.sol";
import {ReentrancyGuard} from "../common/ReentrancyGuard.sol";
import {IZkSyncHyperchain} from "../state-transition/chain-interfaces/IZkSyncHyperchain.sol";
import {ETH_TOKEN_ADDRESS, TWO_BRIDGES_MAGIC_VALUE, BRIDGEHUB_MIN_SECOND_BRIDGE_ADDRESS, NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS} from "../common/Config.sol";
import {ETH_TOKEN_ADDRESS, TWO_BRIDGES_MAGIC_VALUE, BRIDGEHUB_MIN_SECOND_BRIDGE_ADDRESS} from "../common/Config.sol";
import {L2_NATIVE_TOKEN_VAULT_ADDRESS} from "../common/L2ContractAddresses.sol";
import {BridgehubL2TransactionRequest, L2Message, L2Log, TxStatus} from "../common/Messaging.sol";
import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol";

Expand Down Expand Up @@ -46,11 +47,12 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
/// @notice to avoid parity hack
constructor() reentrancyGuardInitializer {
ETH_TOKEN_ASSET_ID = keccak256(
abi.encode(block.chainid, NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS, bytes32(uint256(uint160(ETH_TOKEN_ADDRESS))))
abi.encode(block.chainid, L2_NATIVE_TOKEN_VAULT_ADDRESS, bytes32(uint256(uint160(ETH_TOKEN_ADDRESS))))
);
}

/// @notice used to initialize the contract
/// @notice this contract is also deployed on L2 as a system contract there the owner and the related functions will not be used
function initialize(address _owner) external reentrancyGuardInitializer {
_transferOwnership(_owner);
}
Expand Down Expand Up @@ -133,7 +135,8 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
// solhint-disable-next-line no-unused-vars
uint256 _salt,
address _admin,
bytes calldata _initData
bytes calldata _initData,
bytes[] calldata _factoryDeps
) external onlyOwnerOrAdmin nonReentrant whenNotPaused returns (uint256) {
require(_chainId != 0, "Bridgehub: chainId cannot be 0");
require(_chainId <= type(uint48).max, "Bridgehub: chainId too large");
Expand All @@ -157,7 +160,8 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
_baseToken: _baseToken,
_sharedBridge: address(sharedBridge),
_admin: _admin,
_diamondCut: _initData
_initData: _initData,
_factoryDeps: _factoryDeps
});

emit NewChain(_chainId, _stateTransitionManager, _admin);
Expand Down
3 changes: 2 additions & 1 deletion l1-contracts/contracts/bridgehub/IBridgehub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ interface IBridgehub {
address _baseToken,
uint256 _salt,
address _admin,
bytes calldata _initData
bytes calldata _initData,
bytes[] calldata _factoryDeps
) external returns (uint256 chainId);

function addStateTransitionManager(address _stateTransitionManager) external;
Expand Down
19 changes: 10 additions & 9 deletions l1-contracts/contracts/bridgehub/MessageRoot.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ pragma solidity 0.8.24;
// slither-disable-next-line unused-return
// solhint-disable reason-string, gas-custom-errors

import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
// import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
// import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import {DynamicIncrementalMerkle} from "../common/libraries/openzeppelin/IncrementalMerkle.sol"; // todo figure out how to import from OZ

import {IBridgehub} from "./IBridgehub.sol";
Expand All @@ -21,7 +21,7 @@ import {ReentrancyGuard} from "../common/ReentrancyGuard.sol";

import {FullMerkle} from "../common/libraries/FullMerkle.sol";

contract MessageRoot is IMessageRoot, ReentrancyGuard, Ownable2StepUpgradeable, PausableUpgradeable {
contract MessageRoot is IMessageRoot, ReentrancyGuard {
using FullMerkle for FullMerkle.FullTree;
using DynamicIncrementalMerkle for DynamicIncrementalMerkle.Bytes32PushTree;
/// @dev Bridgehub smart contract that is used to operate with L2 via asynchronous L2 <-> L1 communication.
Expand Down Expand Up @@ -53,17 +53,18 @@ contract MessageRoot is IMessageRoot, ReentrancyGuard, Ownable2StepUpgradeable,
/// @dev Contract is expected to be used as proxy implementation.
/// @dev Initialize the implementation to prevent Parity hack.
constructor(IBridgehub _bridgehub) reentrancyGuardInitializer {
_disableInitializers();
BRIDGE_HUB = _bridgehub;
_initialize();
}

/// @dev Initializes a contract for later use. Expected to be used in the proxy
/// @param _owner Address which can change
function initialize(address _owner) external reentrancyGuardInitializer initializer {
require(_owner != address(0), "ShB owner 0");
/// @dev Initializes a contract for later use. Expected to be used in the proxy on L1, on L2 it is a system contract without a proxy.
function initialize() external reentrancyGuardInitializer {
_initialize();
}

function _initialize() internal {
// slither-disable-next-line unused-return
sharedTree.setup(bytes32(0));
_transferOwnership(_owner);
}

function addNewChain(uint256 _chainId) external onlyBridgehub {
Expand Down
5 changes: 0 additions & 5 deletions l1-contracts/contracts/common/Config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,5 @@ address constant ETH_TOKEN_ADDRESS = address(1);

bytes32 constant TWO_BRIDGES_MAGIC_VALUE = bytes32(uint256(keccak256("TWO_BRIDGES_MAGIC_VALUE")) - 1);

/// @dev A virtual address, used in the assetId calculation for native assets.
/// This is needed for automatic bridging, i.e. without deploying the AssetHandler contract,
/// if the assetId can be calculated with this address then it is in fact an NTV asset
address constant NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS = address(2);

/// @dev https://eips.ethereum.org/EIPS/eip-1352
address constant BRIDGEHUB_MIN_SECOND_BRIDGE_ADDRESS = address(uint160(type(uint16).max));
14 changes: 14 additions & 0 deletions l1-contracts/contracts/common/L2ContractAddresses.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,17 @@ address constant L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR = address(0x800b);

/// @dev The address of the pubdata chunk publisher contract
address constant L2_PUBDATA_CHUNK_PUBLISHER_ADDR = address(0x8011);

/// @dev The address used to execute complex upgragedes, also used for the genesis upgrade
address constant L2_COMPLEX_UPGRADER_ADDR = address(0x800f);

/// @dev The address used to execute the genesis upgrade
address constant L2_GENESIS_UPGRADE_ADDR = address(0x10001);

/// @dev Todo
kelemeno marked this conversation as resolved.
Show resolved Hide resolved
address constant L2_BRIDGEHUB_ADDR = address(0x10002);

/// @dev An l2 system contract address, used in the assetId calculation for native assets.
/// This is needed for automatic bridging, i.e. without deploying the AssetHandler contract,
/// if the assetId can be calculated with this address then it is in fact an NTV asset
address constant L2_NATIVE_TOKEN_VAULT_ADDRESS = address(0x10004);
18 changes: 18 additions & 0 deletions l1-contracts/contracts/common/libraries/L2ContractHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ pragma solidity 0.8.24;

// solhint-disable gas-custom-errors

import {UncheckedMath} from "./UncheckedMath.sol";

/**
* @author Matter Labs
* @custom:security-contact [email protected]
* @notice Helper library for working with L2 contracts on L1.
*/
library L2ContractHelper {
using UncheckedMath for uint256;

/// @dev The prefix used to create CREATE2 addresses.
bytes32 private constant CREATE2_PREFIX = keccak256("zksyncCreate2");

Expand Down Expand Up @@ -73,4 +77,18 @@ library L2ContractHelper {

return address(uint160(uint256(data)));
}

/// @notice Hashes the L2 bytecodes and returns them in the format in which they are processed by the bootloader
function hashFactoryDeps(bytes[] memory _factoryDeps) internal pure returns (uint256[] memory hashedFactoryDeps) {
uint256 factoryDepsLen = _factoryDeps.length;
hashedFactoryDeps = new uint256[](factoryDepsLen);
for (uint256 i = 0; i < factoryDepsLen; i = i.uncheckedInc()) {
bytes32 hashedBytecode = hashL2Bytecode(_factoryDeps[i]);

// Store the resulting hash sequentially in bytes.
assembly {
mstore(add(hashedFactoryDeps, mul(add(i, 1), 32)), hashedBytecode)
}
}
}
}
6 changes: 4 additions & 2 deletions l1-contracts/contracts/dev-contracts/test/DummyBridgehub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

pragma solidity 0.8.24;

import {NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS, ETH_TOKEN_ADDRESS} from "../../common/Config.sol";
import {ETH_TOKEN_ADDRESS} from "../../common/Config.sol";
import {L2_NATIVE_TOKEN_VAULT_ADDRESS} from "../../common/L2ContractAddresses.sol";

import {IGetters} from "../../state-transition/chain-interfaces/IGetters.sol";

contract DummyBridgehub {
Expand All @@ -14,7 +16,7 @@ contract DummyBridgehub {
keccak256(
abi.encode(
block.chainid,
NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS,
L2_NATIVE_TOKEN_VAULT_ADDRESS,
ETH_TOKEN_ADDRESS
// bytes32(uint256(uint160(IGetters(msg.sender).getBaseToken())))
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {L2TransactionRequestTwoBridgesInner} from "../../bridgehub/IBridgehub.sol";
import {TWO_BRIDGES_MAGIC_VALUE} from "../../common/Config.sol";
import {IL1NativeTokenVault} from "../../bridge/L1NativeTokenVault.sol";
import {NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS} from "../../common/Config.sol";
import {L2_NATIVE_TOKEN_VAULT_ADDRESS} from "../../common/L2ContractAddresses.sol";

contract DummySharedBridge {
IL1NativeTokenVault public nativeTokenVault;
Expand Down Expand Up @@ -146,7 +146,7 @@ contract DummySharedBridge {

/// @dev Used to set the assedAddress for a given assetId.
function setAssetHandlerAddressInitial(bytes32 _additionalData, address _assetHandlerAddress) external {
address sender = msg.sender == address(nativeTokenVault) ? NATIVE_TOKEN_VAULT_VIRTUAL_ADDRESS : msg.sender;
address sender = msg.sender == address(nativeTokenVault) ? L2_NATIVE_TOKEN_VAULT_ADDRESS : msg.sender;
bytes32 assetId = keccak256(abi.encode(uint256(block.chainid), sender, _additionalData));
assetHandlerAddress[assetId] = _assetHandlerAddress;
// assetDeploymentTracker[assetId] = sender;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ struct ChainCreationParams {
uint64 genesisIndexRepeatedStorageChanges;
bytes32 genesisBatchCommitment;
Diamond.DiamondCutData diamondCut;
bytes forceDeploymentsData;
}

interface IStateTransitionManager {
/// @dev Emitted when a new Hyperchain is added
event NewHyperchain(uint256 indexed _chainId, address indexed _hyperchainContract);

/// @dev emitted when an chain registers and a SetChainIdUpgrade happens
event SetChainIdUpgrade(
/// @dev emitted when an chain registers and a GenesisUpgrade happens
event GenesisUpgrade(
address indexed _hyperchain,
L2CanonicalTransaction _l2Transaction,
uint256 indexed _protocolVersion
Expand All @@ -62,7 +63,8 @@ interface IStateTransitionManager {
bytes32 genesisBatchHash,
uint64 genesisIndexRepeatedStorageChanges,
bytes32 genesisBatchCommitment,
bytes32 newInitialCutHash
bytes32 newInitialCutHash,
bytes32 forceDeploymentHash
);

/// @notice new UpgradeCutHash
Expand All @@ -87,7 +89,7 @@ interface IStateTransitionManager {

function initialCutHash() external view returns (bytes32);

function genesisUpgrade() external view returns (address);
function l1GenesisUpgrade() external view returns (address);

function upgradeCutHash(uint256 _protocolVersion) external view returns (bytes32);

Expand All @@ -110,7 +112,8 @@ interface IStateTransitionManager {
address _baseToken,
address _sharedBridge,
address _admin,
bytes calldata _diamondCut
bytes calldata _initData,
bytes[] calldata _factoryDeps
) external;

function registerAlreadyDeployedHyperchain(uint256 _chainId, address _hyperchain) external;
Expand Down
Loading