Skip to content

Commit

Permalink
release v20: Short term fee model + 1.4.1 (#167)
Browse files Browse the repository at this point in the history
Co-authored-by: vladbochok <[email protected]>
Co-authored-by: AntonD3 <[email protected]>
Co-authored-by: Vlad Bochok <[email protected]>
Co-authored-by: koloz <[email protected]>
Co-authored-by: AntonD3 <[email protected]>
Co-authored-by: Bence Haromi <[email protected]>
  • Loading branch information
7 people authored Feb 6, 2024
1 parent d55ea62 commit 9ffd7cf
Show file tree
Hide file tree
Showing 118 changed files with 4,187 additions and 5,686 deletions.
11 changes: 10 additions & 1 deletion .github/workflows/l2-contracts-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ jobs:
- name: Install dependencies
run: yarn

- name: Build artifacts
- name: Build L2 artifacts
run: yarn l2 build

- name: Build L1 artifacts
run: yarn l1 build

- name: Create cache
uses: actions/cache/save@v3
with:
Expand All @@ -31,6 +34,9 @@ jobs:
l2-contracts/artifacts-zk
l2-contracts/cache-zk
l2-contracts/typechain
l1-contracts/artifacts
l1-contracts/cache
l1-contracts/typechain
lint:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -79,6 +85,9 @@ jobs:
l2-contracts/artifacts-zk
l2-contracts/cache-zk
l2-contracts/typechain
l1-contracts/artifacts
l1-contracts/cache
l1-contracts/typechain
- name: Run Era test node
uses: dutterbutter/[email protected]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/system-contracts-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ jobs:
- name: Use era-test-node for testing
uses: dutterbutter/[email protected]
with:
releaseTag: v0.0.1-alpha.boojum
releaseTag: v0.0.1-vm1.4.1

- name: Install dependencies
run: yarn
Expand Down
1 change: 1 addition & 0 deletions .markdownlintignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ l2-contracts/node_modules

# system-contracts
system-contracts/node_modules
system-contracts/bootloader/test_infra/target
22 changes: 14 additions & 8 deletions SystemConfig.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
{
"L2_TX_MAX_GAS_LIMIT": 80000000,
"MAX_PUBDATA_PER_BATCH": 110000,
"PRIORITY_TX_MAX_PUBDATA": 99000,
"FAIR_L2_GAS_PRICE": 500000000,
"GUARANTEED_PUBDATA_BYTES": 2500,
"MAX_TRANSACTIONS_IN_BATCH": 10000,
"REQUIRED_L2_GAS_PRICE_PER_PUBDATA": 800,
"L1_GAS_PER_PUBDATA_BYTE": 17,
"BATCH_OVERHEAD_L2_GAS": 1200000,
"PRIORITY_TX_MAX_PUBDATA": 99000,
"BATCH_OVERHEAD_L1_GAS": 1000000,
"MAX_TRANSACTIONS_IN_BATCH": 1024,
"BOOTLOADER_TX_ENCODING_SPACE": 8740224,
"L1_TX_INTRINSIC_L2_GAS": 167157,
"L1_TX_INTRINSIC_PUBDATA": 88,
"L1_TX_MIN_L2_GAS_BASE": 173484,
"L1_TX_DELTA_544_ENCODING_BYTES": 1656,
"L1_TX_DELTA_FACTORY_DEPS_L2_GAS": 2473,
"L1_TX_DELTA_FACTORY_DEPS_PUBDATA": 64,
"L2_TX_INTRINSIC_GAS": 14070,
"L2_TX_INTRINSIC_PUBDATA": 0,
"MAX_NEW_FACTORY_DEPS": 32,
"REQUIRED_L2_GAS_PRICE_PER_PUBDATA": 800
"MAX_GAS_PER_TRANSACTION": 80000000,
"KECCAK_ROUND_COST_GAS": 40,
"SHA256_ROUND_COST_GAS": 7,
"ECRECOVER_COST_GAS": 7000,
"PRIORITY_TX_MINIMAL_GAS_PRICE": 250000000,
"PRIORITY_TX_MAX_GAS_PER_BATCH": 80000000,
"PRIORITY_TX_PUBDATA_PER_BATCH": 120000,
"PRIORITY_TX_BATCH_OVERHEAD_L1_GAS": 1000000
}
2 changes: 1 addition & 1 deletion docs/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ data from L2 and to prove that they were sent on L1 using only `l2ToL1log`. To s
this trick:

- One of the system contracts accepts an arbitrary length message and sends a fixed length message with parameters
`senderAddress == this`, `marker == true`, `key == msg.sender`, `value == keccak256(message)`.
`senderAddress == this`, `isService == true`, `key == msg.sender`, `value == keccak256(message)`.
- The contract on L1 accepts all sent messages and if the message came from this system contract it requires that the
preimage of `value` be provided.

Expand Down
49 changes: 29 additions & 20 deletions l1-contracts/contracts/bridge/L1ERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,24 @@

pragma solidity 0.8.20;

import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

import "./interfaces/IL1BridgeLegacy.sol";
import "./interfaces/IL1Bridge.sol";
import "./interfaces/IL2Bridge.sol";
import "./interfaces/IL2ERC20Bridge.sol";
import {IL1BridgeLegacy} from "./interfaces/IL1BridgeLegacy.sol";
import {IL1Bridge} from "./interfaces/IL1Bridge.sol";
import {IL2Bridge} from "./interfaces/IL2Bridge.sol";
import {IL2ERC20Bridge} from "./interfaces/IL2ERC20Bridge.sol";

import "./libraries/BridgeInitializationHelper.sol";
import {BridgeInitializationHelper} from "./libraries/BridgeInitializationHelper.sol";

import "../zksync/interfaces/IZkSync.sol";
import "../common/libraries/UnsafeBytes.sol";
import "../common/libraries/L2ContractHelper.sol";
import "../common/ReentrancyGuard.sol";
import "../vendor/AddressAliasHelper.sol";
import {IZkSync} from "../zksync/interfaces/IZkSync.sol";
import {TxStatus} from "../zksync/interfaces/IMailbox.sol";
import {L2Message} from "../zksync/Storage.sol";
import {UnsafeBytes} from "../common/libraries/UnsafeBytes.sol";
import {L2ContractHelper} from "../common/libraries/L2ContractHelper.sol";
import {ReentrancyGuard} from "../common/ReentrancyGuard.sol";
import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol";

/// @author Matter Labs
/// @custom:security-contact [email protected]
Expand All @@ -31,11 +34,13 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard {

/// @dev A mapping L2 batch number => message number => flag
/// @dev Used to indicate that zkSync L2 -> L1 message was already processed
mapping(uint256 => mapping(uint256 => bool)) public isWithdrawalFinalized;
mapping(uint256 l2BatchNumber => mapping(uint256 l2ToL1MessageNumber => bool isFinalized))
public isWithdrawalFinalized;

/// @dev A mapping account => L1 token address => L2 deposit transaction hash => amount
/// @dev Used for saving the number of deposited funds, to claim them in case the deposit transaction will fail
mapping(address => mapping(address => mapping(bytes32 => uint256))) internal depositAmount;
mapping(address account => mapping(address l1Token => mapping(bytes32 depositL2TxHash => uint256 amount)))
internal depositAmount;

/// @dev The address of deployed L2 bridge counterpart
address public l2Bridge;
Expand All @@ -46,14 +51,14 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard {
/// @dev The bytecode hash of the L2 token contract
bytes32 public l2TokenProxyBytecodeHash;

mapping(address => uint256) public __DEPRECATED_lastWithdrawalLimitReset;
mapping(address => uint256) private __DEPRECATED_lastWithdrawalLimitReset;

/// @dev A mapping L1 token address => the accumulated withdrawn amount during the withdrawal limit window
mapping(address => uint256) public __DEPRECATED_withdrawnAmountInWindow;
mapping(address => uint256) private __DEPRECATED_withdrawnAmountInWindow;

/// @dev The accumulated deposited amount per user.
/// @dev A mapping L1 token address => user address => the total deposited amount by the user
mapping(address => mapping(address => uint256)) public totalDepositedAmountPerUser;
mapping(address => mapping(address => uint256)) private __DEPRECATED_totalDepositedAmountPerUser;

/// @dev Contract is expected to be used as proxy implementation.
/// @dev Initialize the implementation to prevent Parity hack.
Expand Down Expand Up @@ -119,14 +124,16 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard {
_deployBridgeProxyFee,
l2BridgeProxyBytecodeHash,
l2BridgeProxyConstructorData,
// No factory deps are needed for L2 bridge proxy, because it is already passed in previous step
// No factory deps are needed for the L2 bridge proxy, because it is already passed in previous step
new bytes[](0)
);
}

/// @notice Legacy deposit method with refunding the fee to the caller, use another `deposit` method instead.
/// @dev Initiates a deposit by locking funds on the contract and sending the request
/// of processing an L2 transaction where tokens would be minted
/// of processing an L2 transaction where tokens would be minted.
/// @dev If the token is bridged for the first time, the L2 token contract will be deployed. Note however, that the
/// newly-deployed token does not support any custom logic, i.e. rebase tokens' functionality is not supported.
/// @param _l2Receiver The account address that should receive funds on L2
/// @param _l1Token The L1 token address which is deposited
/// @param _amount The total amount of tokens to be bridged
Expand All @@ -146,6 +153,8 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard {

/// @notice Initiates a deposit by locking funds on the contract and sending the request
/// of processing an L2 transaction where tokens would be minted
/// @dev If the token is bridged for the first time, the L2 token contract will be deployed. Note however, that the
/// newly-deployed token does not support any custom logic, i.e. rebase tokens' functionality is not supported.
/// @param _l2Receiver The account address that should receive funds on L2
/// @param _l1Token The L1 token address which is deposited
/// @param _amount The total amount of tokens to be bridged
Expand Down Expand Up @@ -326,7 +335,7 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard {

/// @return The L2 token address that would be minted for deposit of the given L1 token
function l2TokenAddress(address _l1Token) public view returns (address) {
bytes32 constructorInputHash = keccak256(abi.encode(address(l2TokenBeacon), ""));
bytes32 constructorInputHash = keccak256(abi.encode(l2TokenBeacon, ""));
bytes32 salt = bytes32(uint256(uint160(_l1Token)));

return L2ContractHelper.computeCreate2Address(l2Bridge, salt, l2TokenProxyBytecodeHash, constructorInputHash);
Expand Down
35 changes: 20 additions & 15 deletions l1-contracts/contracts/bridge/L1WethBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@

pragma solidity 0.8.20;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "./interfaces/IL1Bridge.sol";
import "./interfaces/IL2WethBridge.sol";
import "./interfaces/IL2Bridge.sol";
import "./interfaces/IWETH9.sol";
import "../zksync/interfaces/IZkSync.sol";
import {IL1Bridge} from "./interfaces/IL1Bridge.sol";
import {IL2WethBridge} from "./interfaces/IL2WethBridge.sol";
import {IL2Bridge} from "./interfaces/IL2Bridge.sol";
import {IWETH9} from "./interfaces/IWETH9.sol";
import {IZkSync} from "../zksync/interfaces/IZkSync.sol";

import "./libraries/BridgeInitializationHelper.sol";
import {BridgeInitializationHelper} from "./libraries/BridgeInitializationHelper.sol";

import "../common/libraries/UnsafeBytes.sol";
import "../common/ReentrancyGuard.sol";
import "../common/libraries/L2ContractHelper.sol";
import {IMailbox} from "../zksync/interfaces/IMailbox.sol";
import {L2Message} from "../zksync/Storage.sol";

import {UnsafeBytes} from "../common/libraries/UnsafeBytes.sol";
import {ReentrancyGuard} from "../common/ReentrancyGuard.sol";
import {L2ContractHelper} from "../common/libraries/L2ContractHelper.sol";
import {L2_ETH_TOKEN_SYSTEM_CONTRACT_ADDR} from "../common/L2ContractAddresses.sol";
import "../vendor/AddressAliasHelper.sol";
import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol";

/// @author Matter Labs
/// @custom:security-contact [email protected]
Expand Down Expand Up @@ -52,7 +56,8 @@ contract L1WethBridge is IL1Bridge, ReentrancyGuard {

/// @dev A mapping L2 batch number => message number => flag
/// @dev Used to indicate that zkSync L2 -> L1 WETH message was already processed
mapping(uint256 => mapping(uint256 => bool)) public isWithdrawalFinalized;
mapping(uint256 l2BatchNumber => mapping(uint256 l2ToL1MessageNumber => bool isFinalized))
public isWithdrawalFinalized;

/// @dev Contract is expected to be used as proxy implementation.
/// @dev Initialize the implementation to prevent Parity hack.
Expand All @@ -68,9 +73,9 @@ contract L1WethBridge is IL1Bridge, ReentrancyGuard {
/// @notice _factoryDeps[1] == a raw bytecode of proxy that is used as L2 WETH bridge
/// @param _l2WethAddress Pre-calculated address of L2 WETH token
/// @param _governor Address which can change L2 WETH token implementation and upgrade the bridge
/// @param _deployBridgeImplementationFee The fee that will be paid for the L1 -> L2 transaction for deploying L2
/// @param _deployBridgeImplementationFee The fee that will be paid for the L1 -> L2 transaction for deploying the L2
/// bridge implementation
/// @param _deployBridgeProxyFee The fee that will be paid for the L1 -> L2 transaction for deploying L2 bridge
/// @param _deployBridgeProxyFee The fee that will be paid for the L1 -> L2 transaction for deploying the L2 bridge
/// proxy
function initialize(
bytes[] calldata _factoryDeps,
Expand Down Expand Up @@ -122,7 +127,7 @@ contract L1WethBridge is IL1Bridge, ReentrancyGuard {
_deployBridgeProxyFee,
l2WethBridgeProxyBytecodeHash,
l2WethBridgeProxyConstructorData,
// No factory deps are needed for L2 bridge proxy, because it is already passed in the previous step
// No factory deps are needed for the L2 bridge proxy, because it is already passed in the previous step
new bytes[](0)
);
}
Expand Down
2 changes: 2 additions & 0 deletions l1-contracts/contracts/bridge/interfaces/IL1Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

pragma solidity 0.8.20;

/// @title L1 Bridge contract interface
/// @author Matter Labs
/// @custom:security-contact [email protected]
interface IL1Bridge {
event DepositInitiated(
bytes32 indexed l2DepositTxHash,
Expand Down
2 changes: 2 additions & 0 deletions l1-contracts/contracts/bridge/interfaces/IL1BridgeLegacy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

pragma solidity 0.8.20;

/// @title L1 Bridge contract legacy interface
/// @author Matter Labs
/// @custom:security-contact [email protected]
interface IL1BridgeLegacy {
function deposit(
address _l2Receiver,
Expand Down
3 changes: 0 additions & 3 deletions l1-contracts/contracts/common/L2ContractAddresses.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,3 @@ address constant L2_KNOWN_CODE_STORAGE_SYSTEM_CONTRACT_ADDR = address(0x8004);

/// @dev The address of the context system contract
address constant L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR = address(0x800b);

/// @dev The address of the bytecode compressor system contract
address constant L2_BYTECODE_COMPRESSOR_SYSTEM_CONTRACT_ADDR = address(0x800e);
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pragma solidity 0.8.20;
*/
library L2ContractHelper {
/// @dev The prefix used to create CREATE2 addresses.
bytes32 constant CREATE2_PREFIX = keccak256("zksyncCreate2");
bytes32 private constant CREATE2_PREFIX = keccak256("zksyncCreate2");

/// @notice Validate the bytecode format and calculate its hash.
/// @param _bytecode The bytecode to hash.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,19 @@ contract CustomUpgradeTest is BaseZkSyncUpgrade {
/// @notice Placeholder function for custom logic for upgrading L1 contract.
/// Typically this function will never be used.
/// @param _customCallDataForUpgrade Custom data for upgrade, which may be interpreted differently for each upgrade.
function _upgradeL1Contract(bytes calldata _customCallDataForUpgrade) internal {
function _upgradeL1Contract(bytes calldata _customCallDataForUpgrade) internal override {
emit Test();
}

/// @notice placeholder function for custom logic for post-upgrade logic.
/// Typically this function will never be used.
/// @param _customCallDataForUpgrade Custom data for an upgrade, which may be interpreted differently for each
/// upgrade.
function _postUpgrade(bytes calldata _customCallDataForUpgrade) internal virtual {}
function _postUpgrade(bytes calldata _customCallDataForUpgrade) internal override {}

/// @notice The main function that will be called by the upgrade proxy.
/// @param _proposedUpgrade The upgrade to be executed.
function upgrade(ProposedUpgrade calldata _proposedUpgrade) public override returns (bytes32) {
super.upgrade(_proposedUpgrade);

_setNewProtocolVersion(_proposedUpgrade.newProtocolVersion);
_upgradeL1Contract(_proposedUpgrade.l1ContractsUpgradeCalldata);
_upgradeVerifier(_proposedUpgrade.verifier, _proposedUpgrade.verifierParams);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pragma solidity 0.8.20;

import "../../bridge/L1ERC20Bridge.sol";
import {IMailbox} from "../../zksync/interfaces/IMailbox.sol";

/// @author Matter Labs
contract L1ERC20BridgeTest is L1ERC20Bridge {
Expand Down
20 changes: 20 additions & 0 deletions l1-contracts/contracts/dev-contracts/test/MailboxFacetTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.20;

import "../../zksync/facets/Mailbox.sol";
import "../../zksync/Config.sol";

contract MailboxFacetTest is MailboxFacet {
constructor() {
s.governor = msg.sender;
}

function setFeeParams(FeeParams memory _feeParams) external {
s.feeParams = _feeParams;
}

function getL2GasPrice(uint256 _l1GasPrice) external view returns (uint256) {
return _deriveL2GasPrice(_l1GasPrice, REQUIRED_L2_GAS_PRICE_PER_PUBDATA);
}
}
Loading

0 comments on commit 9ffd7cf

Please sign in to comment.