Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x8696A96c606BD48872E7e42FCBeF41c250E8792A
Balance 0 ETH
Nonce 1
Code Size 5340 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

5340 bytes
0x6080604052600436106100d65760003560e01c80635d38962d1161007f5780638da5cb5b116100595780638da5cb5b1461025b578063e0714df614610270578063f2fde38b14610283578063f46901ed146102a357610135565b80635d38962d1461020f578063715018a61461022457806389afc0f11461023957610135565b80631faec686116100b05780631faec686146101a7578063235e5199146101c75780635c975abb146101ed57610135565b8063017e7e581461013a5780631d095805146101655780631ec4247a1461018757610135565b366101355760026001541415610121576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101189061132e565b60405180910390fd5b600260015561012f336102c3565b60018055005b600080fd5b34801561014657600080fd5b5061014f610723565b60405161015c9190611202565b60405180910390f35b34801561017157600080fd5b506101856101803660046110f3565b61073f565b005b34801561019357600080fd5b506101856101a2366004610fea565b6107b7565b3480156101b357600080fd5b506101856101c236600461103d565b610876565b3480156101d357600080fd5b506101dc61094a565b60405161015c95949392919061142e565b3480156101f957600080fd5b50610202610a11565b60405161015c9190611223565b34801561021b57600080fd5b5061014f610a1a565b34801561023057600080fd5b50610185610a3b565b34801561024557600080fd5b5061024e610b1d565b60405161015c9190611425565b34801561026757600080fd5b5061014f610b23565b61018561027e366004610fea565b610b3f565b34801561028f57600080fd5b5061018561029e366004610fea565b610b91565b3480156102af57600080fd5b506101856102be366004610fea565b610cde565b6102cb610a11565b15610302576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101189061128b565b600254610100900473ffffffffffffffffffffffffffffffffffffffff16610356576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610118906112c2565b600061271060035434028161036757fe5b6002546005546008546007546009546040517f71623274000000000000000000000000000000000000000000000000000000008152969095049650348790039560009561010090950473ffffffffffffffffffffffffffffffffffffffff16946371623274946103e09490939092909190600401611464565b60206040518083038186803b1580156103f857600080fd5b505afa15801561040c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104309190611025565b6002805460408051610120810182526005548152602080820188905273ffffffffffffffffffffffffffffffffffffffff8a811683850152612710612af8880204890360608401819052600680548651610100600183161581027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190921699909904601f810186900486028a0186019097528689529899509097909504169463d52471c1948994608085019383018282801561052e5780601f106105035761010080835404028352916020019161052e565b820191906000526020600020905b81548152906001019060200180831161051157829003601f168201915b505050505081526020016005600201548152602001600560040154815260200160058001805480602002602001604051908101604052809291908181526020016000905b8282101561063b5760008481526020908190208301805460408051601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001871615020190941693909304928301859004850281018501909152818152928301828280156106275780601f106105fc57610100808354040283529160200191610627565b820191906000526020600020905b81548152906001019060200180831161060a57829003601f168201915b505050505081526020019060010190610572565b5050505081526020018973ffffffffffffffffffffffffffffffffffffffff168152506040518363ffffffff1660e01b815260040161067a9190611365565b6020604051808303818588803b15801561069357600080fd5b505af11580156106a7573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906106cc9190611025565b50831561071c5760045460405173ffffffffffffffffffffffffffffffffffffffff9091169085156108fc029086906000818181858888f1935050505015801561071a573d6000803e3d6000fd5b505b5050505050565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b610747610d98565b73ffffffffffffffffffffffffffffffffffffffff16610765610b23565b73ffffffffffffffffffffffffffffffffffffffff16146107b2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610118906112f9565b600355565b6107bf610d98565b73ffffffffffffffffffffffffffffffffffffffff166107dd610b23565b73ffffffffffffffffffffffffffffffffffffffff161461082a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610118906112f9565b6002805473ffffffffffffffffffffffffffffffffffffffff909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b61087e610d98565b73ffffffffffffffffffffffffffffffffffffffff1661089c610b23565b73ffffffffffffffffffffffffffffffffffffffff16146108e9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610118906112f9565b80516005908155602080830151805184939261090a92600692910190610d9c565b5060408201516002820155606082015160038201556080820151600482015560a08201518051610944916005840191602090910190610e1a565b50505050565b600580546006805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815293949392918301828280156109f55780601f106109ca576101008083540402835291602001916109f5565b820191906000526020600020905b8154815290600101906020018083116109d857829003601f168201915b5050505050908060020154908060030154908060040154905085565b60025460ff1690565b600254610100900473ffffffffffffffffffffffffffffffffffffffff1681565b610a43610d98565b73ffffffffffffffffffffffffffffffffffffffff16610a61610b23565b73ffffffffffffffffffffffffffffffffffffffff1614610aae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610118906112f9565b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b60035481565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b60026001541415610b7c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101189061132e565b6002600155610b8a816102c3565b5060018055565b610b99610d98565b73ffffffffffffffffffffffffffffffffffffffff16610bb7610b23565b73ffffffffffffffffffffffffffffffffffffffff1614610c04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610118906112f9565b73ffffffffffffffffffffffffffffffffffffffff8116610c51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101189061122e565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610ce6610d98565b73ffffffffffffffffffffffffffffffffffffffff16610d04610b23565b73ffffffffffffffffffffffffffffffffffffffff1614610d51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610118906112f9565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b3390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610ddd57805160ff1916838001178555610e0a565b82800160010185558215610e0a579182015b82811115610e0a578251825591602001919060010190610def565b50610e16929150610e73565b5090565b828054828255906000526020600020908101928215610e67579160200282015b82811115610e675782518051610e57918491602090910190610d9c565b5091602001919060010190610e3a565b50610e16929150610e88565b5b80821115610e165760008155600101610e74565b80821115610e16576000610e9c8282610ea5565b50600101610e88565b50805460018160011615610100020316600290046000825580601f10610ecb5750610ee9565b601f016020900490600052602060002090810190610ee99190610e73565b50565b600082601f830112610efc578081fd5b813567ffffffffffffffff811115610f12578182fd5b6020610f21818284020161147f565b828152925080830184820160005b84811015610f5857610f46888584358a0101610f63565b83529183019190830190600101610f2f565b505050505092915050565b600082601f830112610f73578081fd5b813567ffffffffffffffff811115610f89578182fd5b610fba60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161147f565b9150808252836020828501011115610fd157600080fd5b8060208401602084013760009082016020015292915050565b600060208284031215610ffb578081fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461101e578182fd5b9392505050565b600060208284031215611036578081fd5b5051919050565b60006020828403121561104e578081fd5b813567ffffffffffffffff80821115611065578283fd5b9083019060c08286031215611078578283fd5b61108260c061147f565b82358152602083013582811115611097578485fd5b6110a387828601610f63565b60208301525060408301356040820152606083013560608201526080830135608082015260a0830135828111156110d8578485fd5b6110e487828601610eec565b60a08301525095945050505050565b600060208284031215611104578081fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff169052565b60008282518085526020808601955080818302840101818601855b8481101561118c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301895261117a838351611199565b98840198925090830190600101611140565b5090979650505050505050565b60008151808452815b818110156111be576020818501810151868301820152016111a2565b818111156111cf5782602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b60208082526010908201527f5061757361626c653a2070617573656400000000000000000000000000000000604082015260600190565b60208082526014908201527f427269646765206164647265737320756e736574000000000000000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000602082528251602083015260208301516040830152604083015161138e606084018261110b565b506060830151608083015260808301516101208060a08501526113b5610140850183611199565b915060a085015160c085015260c085015160e085015260e08501516101007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086850301818701526114068483611125565b93508087015191505061141b8286018261110b565b5090949350505050565b90815260200190565b600086825260a0602083015261144760a0830187611199565b604083019590955250606081019290925260809091015292915050565b93845260208401929092526040830152606082015260800190565b60405181810167ffffffffffffffff8111828210171561149e57600080fd5b60405291905056fea2646970667358221220d645cedb928b73e88cd3dd40f0208b92d3e7214d54a6d694d285599b7a94033664736f6c634300060c0033

Verified Source Code Full Match

Compiler: v0.6.12+commit.27d51765 EVM: istanbul Optimization: Yes (100000 runs)
Ownable.sol 68 lines
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "../utils/Context.sol";
/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}
Pausable.sol 90 lines
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor () internal {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}
ReentrancyGuard.sol 62 lines
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}
AbstractBridge.sol 113 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;

import { IBridgehub, L2TransactionRequestDirect } from './system/IBridgehub.sol';
import { Ownable } from '@openzeppelin/contracts/access/Ownable.sol';
import { ReentrancyGuard } from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
import { Pausable } from '@openzeppelin/contracts/utils/Pausable.sol';

/// @title Abstract Bridge contract
/// @author Pudgy Labs
/// @notice This contract handles bridging of ETH to Layer 2
contract AbstractBridge is Ownable, ReentrancyGuard, Pausable {
  uint256 constant FEE_DECIMALS = 1e4;

  /// @notice Address of the bridge hub contract
  IBridgehub public bridgehub;

  /// @notice Fee percentage for the operator
  uint256 public operatorFee;

  /// @notice Address where the operator fee is sent
  address public feeTo;

  /// @notice Configuration for the ZkBridgeHub
  struct ZkBridgeHubConfig {
    uint256 chainId; // Chain ID of the target Layer 2
    bytes l2Calldata; // Calldata for the Layer 2 transaction
    uint256 l2GasLimit; // Gas limit for the Layer 2 transaction
    uint256 l2GasPrice; // Gas price for the Layer 2 transaction
    uint256 l2GasPerPubdataByteLimit; // Gas per pubdata byte limit for the Layer 2 transaction
    bytes[] factoryDeps; // Factory dependencies for the Layer 2 transaction
  }

  /// @notice Current bridge configuration
  ZkBridgeHubConfig public bridgeConfig;

  /// @param _bridgehub Address of the bridge hub contract
  constructor(address _bridgehub) public Ownable() {
    bridgehub = IBridgehub(_bridgehub);
  }

  /// @notice Sets the operator fee
  /// @param _fee New operator fee
  function setOperatorFee(uint256 _fee) public onlyOwner {
    operatorFee = _fee;
  }

  /// @notice Sets the address where the operator fee is sent
  /// @param _feeTo New fee recipient address
  function setFeeTo(address _feeTo) public onlyOwner {
    feeTo = _feeTo;
  }

  /// @notice Sets the bridge hub contract address
  /// @param _bridgehub New bridge hub contract address
  function setBridgehub(address _bridgehub) public onlyOwner {
    bridgehub = IBridgehub(_bridgehub);
  }

  /// @notice Sets the bridge configuration
  /// @param _bridgeConfig New bridge configuration
  function setBridgeConfig(ZkBridgeHubConfig memory _bridgeConfig) public onlyOwner {
    bridgeConfig = _bridgeConfig;
  }

  /// @notice Handles the deposit of ETH to the bridge
  /// @param _to Address of the recipient on Layer 2
  function _handleDepositEth(address _to) internal whenNotPaused {
    require(address(bridgehub) != address(0), 'Bridge address unset');

    uint256 operatorShare = (msg.value * operatorFee) / FEE_DECIMALS;
    uint256 l1Value = msg.value - operatorShare;

    uint256 gasFee = bridgehub.l2TransactionBaseCost(
      bridgeConfig.chainId,
      bridgeConfig.l2GasPrice,
      bridgeConfig.l2GasLimit,
      bridgeConfig.l2GasPerPubdataByteLimit
    );

    uint256 l2Value = l1Value - ((gasFee * 11000) / FEE_DECIMALS);

    bridgehub.requestL2TransactionDirect{ value: l1Value }(
      L2TransactionRequestDirect(
        bridgeConfig.chainId,
        l1Value,
        _to,
        l2Value,
        bridgeConfig.l2Calldata,
        bridgeConfig.l2GasLimit,
        bridgeConfig.l2GasPerPubdataByteLimit,
        bridgeConfig.factoryDeps,
        _to
      )
    );

    if (operatorShare > 0) {
      payable(feeTo).transfer(operatorShare);
    }
  }

  /// @notice Bridges ETH to Layer 2
  /// @param _to Address of the recipient on Layer 2
  function bridgeEth(address _to) external payable nonReentrant {
    _handleDepositEth(_to);
  }

  /// @notice Fallback function to handle direct ETH deposits
  receive() external payable nonReentrant {
    _handleDepositEth(msg.sender);
  }
}
IBridgehub.sol 132 lines
// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;
import {IL1SharedBridge} from "./IL1SharedBridge.sol";
import {L2Message, L2Log, TxStatus} from "./Messaging.sol";

struct L2TransactionRequestDirect {
    uint256 chainId;
    uint256 mintValue;
    address l2Contract;
    uint256 l2Value;
    bytes l2Calldata;
    uint256 l2GasLimit;
    uint256 l2GasPerPubdataByteLimit;
    bytes[] factoryDeps;
    address refundRecipient;
}

struct L2TransactionRequestTwoBridgesOuter {
    uint256 chainId;
    uint256 mintValue;
    uint256 l2Value;
    uint256 l2GasLimit;
    uint256 l2GasPerPubdataByteLimit;
    address refundRecipient;
    address secondBridgeAddress;
    uint256 secondBridgeValue;
    bytes secondBridgeCalldata;
}

struct L2TransactionRequestTwoBridgesInner {
    bytes32 magicValue;
    address l2Contract;
    bytes l2Calldata;
    bytes[] factoryDeps;
    bytes32 txDataHash;
}

interface IBridgehub {
    /// @notice pendingAdmin is changed
    /// @dev Also emitted when new admin is accepted and in this case, `newPendingAdmin` would be zero address
    event NewPendingAdmin(address indexed oldPendingAdmin, address indexed newPendingAdmin);

    /// @notice Admin changed
    event NewAdmin(address indexed oldAdmin, address indexed newAdmin);

    /// @notice Starts the transfer of admin rights. Only the current admin can propose a new pending one.
    /// @notice New admin can accept admin rights by calling `acceptAdmin` function.
    /// @param _newPendingAdmin Address of the new admin
    function setPendingAdmin(address _newPendingAdmin) external;

    /// @notice Accepts transfer of admin rights. Only pending admin can accept the role.
    function acceptAdmin() external;

    /// Getters
    function stateTransitionManagerIsRegistered(address _stateTransitionManager) external view returns (bool);

    function stateTransitionManager(uint256 _chainId) external view returns (address);

    function tokenIsRegistered(address _baseToken) external view returns (bool);

    function baseToken(uint256 _chainId) external view returns (address);

    function sharedBridge() external view returns (IL1SharedBridge);

    function getHyperchain(uint256 _chainId) external view returns (address);

    /// Mailbox forwarder

    function proveL2MessageInclusion(
        uint256 _chainId,
        uint256 _batchNumber,
        uint256 _index,
        L2Message calldata _message,
        bytes32[] calldata _proof
    ) external view returns (bool);

    function proveL2LogInclusion(
        uint256 _chainId,
        uint256 _batchNumber,
        uint256 _index,
        L2Log memory _log,
        bytes32[] calldata _proof
    ) external view returns (bool);

    function proveL1ToL2TransactionStatus(
        uint256 _chainId,
        bytes32 _l2TxHash,
        uint256 _l2BatchNumber,
        uint256 _l2MessageIndex,
        uint16 _l2TxNumberInBatch,
        bytes32[] calldata _merkleProof,
        TxStatus _status
    ) external view returns (bool);

    function requestL2TransactionDirect(
        L2TransactionRequestDirect calldata _request
    ) external payable returns (bytes32 canonicalTxHash);

    function requestL2TransactionTwoBridges(
        L2TransactionRequestTwoBridgesOuter calldata _request
    ) external payable returns (bytes32 canonicalTxHash);

    function l2TransactionBaseCost(
        uint256 _chainId,
        uint256 _gasPrice,
        uint256 _l2GasLimit,
        uint256 _l2GasPerPubdataByteLimit
    ) external view returns (uint256);

    //// Registry

    function createNewChain(
        uint256 _chainId,
        address _stateTransitionManager,
        address _baseToken,
        uint256 _salt,
        address _admin,
        bytes calldata _initData
    ) external returns (uint256 chainId);

    function addStateTransitionManager(address _stateTransitionManager) external;

    function removeStateTransitionManager(address _stateTransitionManager) external;

    function addToken(address _token) external;

    function setSharedBridge(address _sharedBridge) external;

    event NewChain(uint256 indexed chainId, address stateTransitionManager, address indexed chainGovernance);
}
IL1ERC20Bridge.sol 73 lines
// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.6.12;

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


interface IL1ERC20Bridge {
    event DepositInitiated(
        bytes32 indexed l2DepositTxHash,
        address indexed from,
        address indexed to,
        address l1Token,
        uint256 amount
    );

    event WithdrawalFinalized(address indexed to, address indexed l1Token, uint256 amount);

    event ClaimedFailedDeposit(address indexed to, address indexed l1Token, uint256 amount);

    function isWithdrawalFinalized(uint256 _l2BatchNumber, uint256 _l2MessageIndex) external view returns (bool);

    function deposit(
        address _l2Receiver,
        address _l1Token,
        uint256 _amount,
        uint256 _l2TxGasLimit,
        uint256 _l2TxGasPerPubdataByte,
        address _refundRecipient
    ) external payable returns (bytes32 txHash);

    function deposit(
        address _l2Receiver,
        address _l1Token,
        uint256 _amount,
        uint256 _l2TxGasLimit,
        uint256 _l2TxGasPerPubdataByte
    ) external payable returns (bytes32 txHash);

    function claimFailedDeposit(
        address _depositSender,
        address _l1Token,
        bytes32 _l2TxHash,
        uint256 _l2BatchNumber,
        uint256 _l2MessageIndex,
        uint16 _l2TxNumberInBatch,
        bytes32[] calldata _merkleProof
    ) external;

    function finalizeWithdrawal(
        uint256 _l2BatchNumber,
        uint256 _l2MessageIndex,
        uint16 _l2TxNumberInBatch,
        bytes calldata _message,
        bytes32[] calldata _merkleProof
    ) external;

    function l2TokenAddress(address _l1Token) external view returns (address);

    function SHARED_BRIDGE() external view returns (IL1SharedBridge);

    function l2TokenBeacon() external view returns (address);

    function l2Bridge() external view returns (address);

    function depositAmount(
        address _account,
        address _l1Token,
        bytes32 _depositL2TxHash
    ) external returns (uint256 amount);

    function transferTokenToSharedBridge(address _token) external;
}
IL1SharedBridge.sol 166 lines
// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;
import {L2TransactionRequestTwoBridgesInner} from "./IBridgehub.sol";
import {IBridgehub} from "./IBridgehub.sol";
import {IL1ERC20Bridge} from "./IL1ERC20Bridge.sol";

interface IL1SharedBridge {
    /// @notice pendingAdmin is changed
    /// @dev Also emitted when new admin is accepted and in this case, `newPendingAdmin` would be zero address
    event NewPendingAdmin(address indexed oldPendingAdmin, address indexed newPendingAdmin);

    /// @notice Admin changed
    event NewAdmin(address indexed oldAdmin, address indexed newAdmin);

    event LegacyDepositInitiated(
        uint256 indexed chainId,
        bytes32 indexed l2DepositTxHash,
        address indexed from,
        address to,
        address l1Token,
        uint256 amount
    );

    event BridgehubDepositInitiated(
        uint256 indexed chainId,
        bytes32 indexed txDataHash,
        address indexed from,
        address to,
        address l1Token,
        uint256 amount
    );

    event BridgehubDepositBaseTokenInitiated(
        uint256 indexed chainId,
        address indexed from,
        address l1Token,
        uint256 amount
    );

    event BridgehubDepositFinalized(
        uint256 indexed chainId,
        bytes32 indexed txDataHash,
        bytes32 indexed l2DepositTxHash
    );

    event WithdrawalFinalizedSharedBridge(
        uint256 indexed chainId,
        address indexed to,
        address indexed l1Token,
        uint256 amount
    );

    event ClaimedFailedDepositSharedBridge(
        uint256 indexed chainId,
        address indexed to,
        address indexed l1Token,
        uint256 amount
    );

    function isWithdrawalFinalized(
        uint256 _chainId,
        uint256 _l2BatchNumber,
        uint256 _l2MessageIndex
    ) external view returns (bool);

    function depositLegacyErc20Bridge(
        address _msgSender,
        address _l2Receiver,
        address _l1Token,
        uint256 _amount,
        uint256 _l2TxGasLimit,
        uint256 _l2TxGasPerPubdataByte,
        address _refundRecipient
    ) external payable returns (bytes32 txHash);

    function claimFailedDepositLegacyErc20Bridge(
        address _depositSender,
        address _l1Token,
        uint256 _amount,
        bytes32 _l2TxHash,
        uint256 _l2BatchNumber,
        uint256 _l2MessageIndex,
        uint16 _l2TxNumberInBatch,
        bytes32[] calldata _merkleProof
    ) external;

    function claimFailedDeposit(
        uint256 _chainId,
        address _depositSender,
        address _l1Token,
        uint256 _amount,
        bytes32 _l2TxHash,
        uint256 _l2BatchNumber,
        uint256 _l2MessageIndex,
        uint16 _l2TxNumberInBatch,
        bytes32[] calldata _merkleProof
    ) external;

    function finalizeWithdrawalLegacyErc20Bridge(
        uint256 _l2BatchNumber,
        uint256 _l2MessageIndex,
        uint16 _l2TxNumberInBatch,
        bytes calldata _message,
        bytes32[] calldata _merkleProof
    ) external returns (address l1Receiver, address l1Token, uint256 amount);

    function finalizeWithdrawal(
        uint256 _chainId,
        uint256 _l2BatchNumber,
        uint256 _l2MessageIndex,
        uint16 _l2TxNumberInBatch,
        bytes calldata _message,
        bytes32[] calldata _merkleProof
    ) external;

    function setEraPostDiamondUpgradeFirstBatch(uint256 _eraPostDiamondUpgradeFirstBatch) external;

    function setEraPostLegacyBridgeUpgradeFirstBatch(uint256 _eraPostLegacyBridgeUpgradeFirstBatch) external;

    function setEraLegacyBridgeLastDepositTime(
        uint256 _eraLegacyBridgeLastDepositBatch,
        uint256 _eraLegacyBridgeLastDepositTxNumber
    ) external;

    function L1_WETH_TOKEN() external view returns (address);

    function BRIDGE_HUB() external view returns (IBridgehub);

    function legacyBridge() external view returns (IL1ERC20Bridge);

    function l2BridgeAddress(uint256 _chainId) external view returns (address);

    function depositHappened(uint256 _chainId, bytes32 _l2TxHash) external view returns (bytes32);

    /// data is abi encoded :
    /// address _l1Token,
    /// uint256 _amount,
    /// address _l2Receiver
    function bridgehubDeposit(
        uint256 _chainId,
        address _prevMsgSender,
        uint256 _l2Value,
        bytes calldata _data
    ) external payable returns (L2TransactionRequestTwoBridgesInner memory request);

    function bridgehubDepositBaseToken(
        uint256 _chainId,
        address _prevMsgSender,
        address _l1Token,
        uint256 _amount
    ) external payable;

    function bridgehubConfirmL2Transaction(uint256 _chainId, bytes32 _txDataHash, bytes32 _txHash) external;

    function receiveEth(uint256 _chainId) external payable;

    /// @notice Starts the transfer of admin rights. Only the current admin can propose a new pending one.
    /// @notice New admin can accept admin rights by calling `acceptAdmin` function.
    /// @param _newPendingAdmin Address of the new admin
    function setPendingAdmin(address _newPendingAdmin) external;

    /// @notice Accepts transfer of admin rights. Only pending admin can accept the role.
    function acceptAdmin() external;
}
Messaging.sol 136 lines
// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.6.12;

/// @dev The enum that represents the transaction execution status
/// @param Failure The transaction execution failed
/// @param Success The transaction execution succeeded
enum TxStatus {
    Failure,
    Success
}

/// @dev The log passed from L2
/// @param l2ShardId The shard identifier, 0 - rollup, 1 - porter
/// All other values are not used but are reserved for the future
/// @param isService A boolean flag that is part of the log along with `key`, `value`, and `sender` address.
/// This field is required formally but does not have any special meaning
/// @param txNumberInBatch The L2 transaction number in a Batch, in which the log was sent
/// @param sender The L2 address which sent the log
/// @param key The 32 bytes of information that was sent in the log
/// @param value The 32 bytes of information that was sent in the log
// Both `key` and `value` are arbitrary 32-bytes selected by the log sender
struct L2Log {
    uint8 l2ShardId;
    bool isService;
    uint16 txNumberInBatch;
    address sender;
    bytes32 key;
    bytes32 value;
}

/// @dev An arbitrary length message passed from L2
/// @notice Under the hood it is `L2Log` sent from the special system L2 contract
/// @param txNumberInBatch The L2 transaction number in a Batch, in which the message was sent
/// @param sender The address of the L2 account from which the message was passed
/// @param data An arbitrary length message
struct L2Message {
    uint16 txNumberInBatch;
    address sender;
    bytes data;
}

/// @dev Internal structure that contains the parameters for the writePriorityOp
/// internal function.
/// @param txId The id of the priority transaction.
/// @param l2GasPrice The gas price for the l2 priority operation.
/// @param expirationTimestamp The timestamp by which the priority operation must be processed by the operator.
/// @param request The external calldata request for the priority operation.
struct WritePriorityOpParams {
    uint256 txId;
    uint256 l2GasPrice;
    uint64 expirationTimestamp;
    BridgehubL2TransactionRequest request;
}

/// @dev Structure that includes all fields of the L2 transaction
/// @dev The hash of this structure is the "canonical L2 transaction hash" and can
/// be used as a unique identifier of a tx
/// @param txType The tx type number, depending on which the L2 transaction can be
/// interpreted differently
/// @param from The sender's address. `uint256` type for possible address format changes
/// and maintaining backward compatibility
/// @param to The recipient's address. `uint256` type for possible address format changes
/// and maintaining backward compatibility
/// @param gasLimit The L2 gas limit for L2 transaction. Analog to the `gasLimit` on an
/// L1 transactions
/// @param gasPerPubdataByteLimit Maximum number of L2 gas that will cost one byte of pubdata
/// (every piece of data that will be stored on L1 as calldata)
/// @param maxFeePerGas The absolute maximum sender willing to pay per unit of L2 gas to get
/// the transaction included in a Batch. Analog to the EIP-1559 `maxFeePerGas` on an L1 transactions
/// @param maxPriorityFeePerGas The additional fee that is paid directly to the validator
/// to incentivize them to include the transaction in a Batch. Analog to the EIP-1559
/// `maxPriorityFeePerGas` on an L1 transactions
/// @param paymaster The address of the EIP-4337 paymaster, that will pay fees for the
/// transaction. `uint256` type for possible address format changes and maintaining backward compatibility
/// @param nonce The nonce of the transaction. For L1->L2 transactions it is the priority
/// operation Id
/// @param value The value to pass with the transaction
/// @param reserved The fixed-length fields for usage in a future extension of transaction
/// formats
/// @param data The calldata that is transmitted for the transaction call
/// @param signature An abstract set of bytes that are used for transaction authorization
/// @param factoryDeps The set of L2 bytecode hashes whose preimages were shown on L1
/// @param paymasterInput The arbitrary-length data that is used as a calldata to the paymaster pre-call
/// @param reservedDynamic The arbitrary-length field for usage in a future extension of transaction formats
struct L2CanonicalTransaction {
    uint256 txType;
    uint256 from;
    uint256 to;
    uint256 gasLimit;
    uint256 gasPerPubdataByteLimit;
    uint256 maxFeePerGas;
    uint256 maxPriorityFeePerGas;
    uint256 paymaster;
    uint256 nonce;
    uint256 value;
    // In the future, we might want to add some
    // new fields to the struct. The `txData` struct
    // is to be passed to account and any changes to its structure
    // would mean a breaking change to these accounts. To prevent this,
    // we should keep some fields as "reserved"
    // It is also recommended that their length is fixed, since
    // it would allow easier proof integration (in case we will need
    // some special circuit for preprocessing transactions)
    uint256[4] reserved;
    bytes data;
    bytes signature;
    uint256[] factoryDeps;
    bytes paymasterInput;
    // Reserved dynamic type for the future use-case. Using it should be avoided,
    // But it is still here, just in case we want to enable some additional functionality
    bytes reservedDynamic;
}

/// @param sender The sender's address.
/// @param contractAddressL2 The address of the contract on L2 to call.
/// @param valueToMint The amount of base token that should be minted on L2 as the result of this transaction.
/// @param l2Value The msg.value of the L2 transaction.
/// @param l2Calldata The calldata for the L2 transaction.
/// @param l2GasLimit The limit of the L2 gas for the L2 transaction
/// @param l2GasPerPubdataByteLimit The price for a single pubdata byte in L2 gas.
/// @param factoryDeps The array of L2 bytecodes that the tx depends on.
/// @param refundRecipient The recipient of the refund for the transaction on L2. If the transaction fails, then
/// this address will receive the `l2Value`.
// solhint-disable-next-line gas-struct-packing
struct BridgehubL2TransactionRequest {
    address sender;
    address contractL2;
    uint256 mintValue;
    uint256 l2Value;
    bytes l2Calldata;
    uint256 l2GasLimit;
    uint256 l2GasPerPubdataByteLimit;
    bytes[] factoryDeps;
    address refundRecipient;
}

Read Contract

bridgeConfig 0x235e5199 → uint256, bytes, uint256, uint256, uint256
bridgehub 0x5d38962d → address
feeTo 0x017e7e58 → address
operatorFee 0x89afc0f1 → uint256
owner 0x8da5cb5b → address
paused 0x5c975abb → bool

Write Contract 7 functions

These functions modify contract state and require a wallet transaction to execute.

bridgeEth 0xe0714df6
address _to
renounceOwnership 0x715018a6
No parameters
setBridgeConfig 0x9fa00486
tuple _bridgeConfig
setBridgehub 0x1ec4247a
address _bridgehub
setFeeTo 0xf46901ed
address _feeTo
setOperatorFee 0x1d095805
uint256 _fee
transferOwnership 0xf2fde38b
address newOwner

Recent Transactions

No transactions found for this address