Skip to content

Commit

Permalink
Library fix review (#1146)
Browse files Browse the repository at this point in the history
Signed-off-by: Danil <[email protected]>
Co-authored-by: kelemeno <[email protected]>
Co-authored-by: Stanislav Breadless <[email protected]>
Co-authored-by: Raid Ateir <[email protected]>
Co-authored-by: Grzegorz Prusak <[email protected]>
Co-authored-by: Moshe Shababo <[email protected]>
Co-authored-by: Akosh Farkash <[email protected]>
Co-authored-by: Bruno França <[email protected]>
Co-authored-by: Vlad Bochok <[email protected]>
Co-authored-by: Roman Brodetski <[email protected]>
Co-authored-by: vladbochok <[email protected]>
Co-authored-by: Danil <[email protected]>
Co-authored-by: kelemeno <[email protected]>
Co-authored-by: Neo <[email protected]>
Co-authored-by: tommysr <[email protected]>
Co-authored-by: Rahul Saxena <[email protected]>
Co-authored-by: Artem Makhortov <[email protected]>
Co-authored-by: Bence Haromi <[email protected]>
Co-authored-by: Zach Kolodny <[email protected]>
Co-authored-by: perekopskiy <[email protected]>
Co-authored-by: perekopskiy <[email protected]>
Co-authored-by: Ivan Schasny <[email protected]>
Co-authored-by: mm <[email protected]>
Co-authored-by: Dima Zhornyk <[email protected]>
Co-authored-by: Yberjon <[email protected]>
  • Loading branch information
1 parent 9b940ef commit 45cf28c
Show file tree
Hide file tree
Showing 27 changed files with 179 additions and 235 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/l1-contracts-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ jobs:
- name: Build da-contracts artifacts
run: yarn da build:foundry

- name: Build l1 artifacts
run: yarn l1 build

- name: Create cache
uses: actions/cache/save@v3
with:
Expand Down
8 changes: 4 additions & 4 deletions l1-contracts/contracts/bridge/L1Nullifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -573,8 +573,8 @@ contract L1Nullifier is IL1Nullifier, ReentrancyGuard, Ownable2StepUpgradeable,
address baseToken = BRIDGE_HUB.baseToken(_chainId);
transferData = DataEncoding.encodeBridgeMintData({
_originalCaller: address(0),
_remoteReceiver: l1Receiver,
_originToken: baseToken,
_l2Receiver: l1Receiver,
_l1Token: baseToken,
_amount: amount,
_erc20Metadata: new bytes(0)
});
Expand All @@ -598,8 +598,8 @@ contract L1Nullifier is IL1Nullifier, ReentrancyGuard, Ownable2StepUpgradeable,
assetId = DataEncoding.encodeNTVAssetId(block.chainid, l1Token);
transferData = DataEncoding.encodeBridgeMintData({
_originalCaller: address(0),
_remoteReceiver: l1Receiver,
_originToken: l1Token,
_l2Receiver: l1Receiver,
_l1Token: l1Token,
_amount: amount,
_erc20Metadata: new bytes(0)
});
Expand Down
8 changes: 4 additions & 4 deletions l1-contracts/contracts/bridge/ntv/NativeTokenVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ abstract contract NativeTokenVault is INativeTokenVault, IAssetHandler, Ownable2

_bridgeMintData = DataEncoding.encodeBridgeMintData({
_originalCaller: _originalCaller,
_remoteReceiver: _receiver,
_originToken: originToken,
_l2Receiver: _receiver,
_l1Token: originToken,
_amount: _amount,
_erc20Metadata: erc20Metadata
});
Expand Down Expand Up @@ -295,8 +295,8 @@ abstract contract NativeTokenVault is INativeTokenVault, IAssetHandler, Ownable2
}
_bridgeMintData = DataEncoding.encodeBridgeMintData({
_originalCaller: _originalCaller,
_remoteReceiver: _receiver,
_originToken: nativeToken,
_l2Receiver: _receiver,
_l1Token: nativeToken,
_amount: amount,
_erc20Metadata: erc20Metadata
});
Expand Down
24 changes: 10 additions & 14 deletions l1-contracts/contracts/common/L1ContractErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ error ChainIdCantBeCurrentChain();
error ChainIdMismatch();
// 0x23f3c357
error ChainIdNotRegistered(uint256 chainId);
// 0x5de72107
error ChainNotLegacy();
// 0x8f620a06
error ChainIdTooBig();
// 0xf7a01e4d
Expand All @@ -87,12 +89,16 @@ error DiamondNotFrozen();
error EmptyAddress();
// 0x2d4d012f
error EmptyAssetId();
// 0xfc7ab1d3
error EmptyBlobVersionHash(uint256 index);
// 0x1c25715b
error EmptyBytes32();
// 0x95b66fe9
error EmptyDeposit();
// 0x627e0872
error ETHDepositNotSupported();
// 0x1bdfd505
error FailedToTransferTokens(address tokenContract, address to, uint256 amount);
// 0xac4a3f98
error FacetExists(bytes4 selector, address);
// 0xc91cf3b1
Expand All @@ -115,6 +121,8 @@ error ZKChainLimitReached();
error IncorrectBridgeHubAddress(address bridgehub);
// 0x826fb11e
error InsufficientChainBalance();
// 0x356680b7
error InsufficientFunds();
// 0xcbd9d2e0
error InvalidCaller(address);
// 0x4fbe5dba
Expand Down Expand Up @@ -314,10 +322,10 @@ error IncorrectBatchBounds(
);
// 0x64107968
error AssetHandlerNotRegistered(bytes32 assetId);
// 0x64846fe4
error NotARestriction(address addr);
// 0xfa5cd00f
error NotAllowed(address addr);
// 0x64846fe4
error NotARestriction(address addr);
// 0xccdd18d2
error BytecodeAlreadyPublished(bytes32 bytecodeHash);
// 0x25d8333c
Expand All @@ -338,22 +346,10 @@ error IncorrectPricingMode();
error NotSettlementLayer();
// 0x7a4902ad
error TimerAlreadyStarted();

// 0x09aa9830
error MerklePathLengthMismatch(uint256 pathLength, uint256 expectedLength);

// 0xc33e6128
error MerkleNothingToProve();

// 0xafbb7a4e
error MerkleIndexOrHeightMismatch();

// 0x1b582fcf
error MerkleWrongIndex(uint256 index, uint256 maxNodeNumber);

// 0x485cfcaa
error MerkleWrongLength(uint256 newLeavesLength, uint256 leafNumber);

// 0xce63ce17
error NoCTMForAssetId(bytes32 assetId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ pragma solidity ^0.8.21;

/**
* @author Matter Labs
* @notice System smart contract that is responsible for deploying other smart contracts on a ZK chain.
* @custom:security-contact [email protected]
* @notice Interface for the contract that is used to deploy contracts on L2.
* @dev Identical interface is defined in L2ContractHelper library. Duplication is for testing purposes only.
*/
interface IL2ContractDeployer {
/// @notice A struct that describes a forced deployment on an address.
Expand Down
57 changes: 31 additions & 26 deletions l1-contracts/contracts/common/libraries/DataEncoding.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,27 @@ import {UnsupportedEncodingVersion} from "../L1ContractErrors.sol";
library DataEncoding {
/// @notice Abi.encodes the data required for bridgeMint on remote chain.
/// @param _originalCaller The address which initiated the transfer.
/// @param _remoteReceiver The address which to receive tokens on remote chain.
/// @param _originToken The transferred token address.
/// @param _l2Receiver The address which to receive tokens on remote chain.
/// @param _l1Token The transferred token address.
/// @param _amount The amount of token to be transferred.
/// @param _erc20Metadata The transferred token metadata.
/// @return The encoded bridgeMint data
function encodeBridgeMintData(
address _originalCaller,
address _remoteReceiver,
address _originToken,
address _l2Receiver,
address _l1Token,
uint256 _amount,
bytes memory _erc20Metadata
) internal pure returns (bytes memory) {
// solhint-disable-next-line func-named-parameters
return abi.encode(_originalCaller, _remoteReceiver, _originToken, _amount, _erc20Metadata);
return abi.encode(_originalCaller, _l2Receiver, _l1Token, _amount, _erc20Metadata);
}

/// @notice Function decoding transfer data previously encoded with this library.
/// @param _bridgeMintData The encoded bridgeMint data
/// @return _originalCaller The address which initiated the transfer.
/// @return _remoteReceiver The address which to receive tokens on remote chain.
/// @return _parsedOriginToken The transferred token address.
/// @return _l2Receiver The address which to receive tokens on remote chain.
/// @return _parsedL1Token The transferred token address.
/// @return _amount The amount of token to be transferred.
/// @return _erc20Metadata The transferred token metadata.
function decodeBridgeMintData(
Expand All @@ -45,18 +45,32 @@ library DataEncoding {
pure
returns (
address _originalCaller,
address _remoteReceiver,
address _parsedOriginToken,
address _l2Receiver,
address _parsedL1Token,
uint256 _amount,
bytes memory _erc20Metadata
)
{
(_originalCaller, _remoteReceiver, _parsedOriginToken, _amount, _erc20Metadata) = abi.decode(
(_originalCaller, _l2Receiver, _parsedL1Token, _amount, _erc20Metadata) = abi.decode(
_bridgeMintData,
(address, address, address, uint256, bytes)
);
}

/// @notice Encodes the legacy transaction data hash.
/// @dev the encoding strats with 0t
/// @param _originalCaller The address of the entity that initiated the deposit.
/// @param _l1Token The address of the L1 token.
/// @param _amount The amount of the L1 token.
/// @return txDataHash The resulting encoded transaction data hash.
function encodeLegacyTxDataHash(
address _originalCaller,
address _l1Token,
uint256 _amount
) internal pure returns (bytes32) {
return keccak256(abi.encode(_originalCaller, _l1Token, _amount));
}

/// @notice Encodes the asset data by combining chain id, asset deployment tracker and asset data.
/// @param _chainId The id of the chain token is native to.
/// @param _assetData The asset data that has to be encoded.
Expand Down Expand Up @@ -108,7 +122,7 @@ library DataEncoding {
if (_encodingVersion == LEGACY_ENCODING_VERSION) {
address tokenAddress = INativeTokenVault(_nativeTokenVault).tokenAddress(_assetId);
(uint256 depositAmount, ) = abi.decode(_transferData, (uint256, address));
txDataHash = encodeLegacyTxDataHash(_originalCaller, tokenAddress, depositAmount);
txDataHash = keccak256(abi.encode(_originalCaller, tokenAddress, depositAmount));
} else if (_encodingVersion == NEW_ENCODING_VERSION) {
// Similarly to calldata, the txDataHash is collision-resistant.
// In the legacy data hash, the first encoded variable was the address, which is padded with zeros during `abi.encode`.
Expand All @@ -120,21 +134,12 @@ library DataEncoding {
}
}

/// @notice Encodes the legacy transaction data hash.
/// @dev the encoding strats with 0t
/// @param _originalCaller The address of the entity that initiated the deposit.
/// @param _l1Token The address of the L1 token.
/// @param _amount The amount of the L1 token.
/// @return txDataHash The resulting encoded transaction data hash.
function encodeLegacyTxDataHash(
address _originalCaller,
address _l1Token,
uint256 _amount
) internal pure returns (bytes32) {
return keccak256(abi.encode(_originalCaller, _l1Token, _amount));
}

/// @notice Decodes the token data by combining chain id, asset deployment tracker and asset data.
/// @notice Decodes the token data
/// @dev Note that all the returned metadata of the token is ABI encoded.
/// @return chainId The chainId of the origin of the token
/// @return name The name of the token.
/// @return symbol The symbol of the token.
/// @return decimals The decimals of the token.
function decodeTokenData(
bytes calldata _tokenData
) internal pure returns (uint256 chainId, bytes memory name, bytes memory symbol, bytes memory decimals) {
Expand Down
17 changes: 6 additions & 11 deletions l1-contracts/contracts/common/libraries/Merkle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// 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.8.21;

// solhint-disable gas-custom-errors

import {UncheckedMath} from "../../common/libraries/UncheckedMath.sol";
import {MerklePathEmpty, MerklePathOutOfBounds, MerkleIndexOutOfBounds, MerklePathLengthMismatch, MerkleNothingToProve, MerkleIndexOrHeightMismatch} from "../../common/L1ContractErrors.sol";
import {MerklePathEmpty, MerklePathOutOfBounds, MerkleIndexOutOfBounds} from "../../common/L1ContractErrors.sol";

/// @author Matter Labs
/// @custom:security-contact [email protected]
Expand All @@ -12,7 +14,6 @@ library Merkle {

/// @dev Calculate Merkle root by the provided Merkle proof.
/// NOTE: When using this function, check that the _path length is equal to the tree height to prevent shorter/longer paths attack
/// however, for chains settling on GW the proof includes the GW proof, so the path increases. See Mailbox for more details.
/// @param _path Merkle path from the leaf to the root
/// @param _index Leaf index in the tree
/// @param _itemHash Hash of leaf content
Expand Down Expand Up @@ -75,9 +76,7 @@ library Merkle {
bytes32[] memory _itemHashes
) internal pure returns (bytes32) {
uint256 pathLength = _startPath.length;
if (pathLength != _endPath.length) {
revert MerklePathLengthMismatch(pathLength, _endPath.length);
}
require(pathLength == _endPath.length, "Merkle: path length mismatch");
if (pathLength >= 256) {
revert MerklePathOutOfBounds();
}
Expand All @@ -86,12 +85,8 @@ library Merkle {
if (pathLength == 0 && (_startIndex != 0 || levelLen != 1)) {
revert MerklePathEmpty();
}
if (levelLen == 0) {
revert MerkleNothingToProve();
}
if (_startIndex + levelLen > (1 << pathLength)) {
revert MerkleIndexOrHeightMismatch();
}
require(levelLen > 0, "Merkle: nothing to prove");
require(_startIndex + levelLen <= (1 << pathLength), "Merkle: index/height mismatch");
bytes32[] memory itemHashes = _itemHashes;

for (uint256 level; level < pathLength; level = level.uncheckedInc()) {
Expand Down
15 changes: 15 additions & 0 deletions l1-contracts/contracts/governance/IRestriction.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import {Call} from "./Common.sol";

/// @title Restriction contract interface
/// @author Matter Labs
/// @custom:security-contact [email protected]
interface IRestriction {
/// @notice Ensures that the invoker has the required role to call the function.
/// @param _call The call data.
/// @param _invoker The address of the invoker.
function validateCall(Call calldata _call, address _invoker) external view;
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ struct ZKChainStorage {
/// @dev The address of the baseToken contract. Eth is address(1)
address __DEPRECATED_baseToken;
/// @dev The address of the baseTokenbridge. Eth also uses the shared bridge
address __DEPRECATED_baseTokenBridge;
/// @notice gasPriceMultiplier for each baseToken, so that each L1->L2 transaction pays for its transaction on the destination
address baseTokenBridge;
/// @notice gasPriceMultiplier for each baseToken, so that each L1->L2 transaction pays for its transaction on the destination
/// we multiply by the nominator, and divide by the denominator
uint128 baseTokenGasPriceMultiplierNominator;
uint128 baseTokenGasPriceMultiplierDenominator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ interface IL2GenesisUpgrade {
function genesisUpgrade(
uint256 _chainId,
address _ctmDeployer,
bytes calldata _fixedForceDeploymentsData,
bytes calldata _additionalForceDeploymentsData
bytes calldata _forceDeploymentsData
) external payable;
}
42 changes: 14 additions & 28 deletions l1-contracts/contracts/upgrades/GatewayUpgrade.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import {DataEncoding} from "../common/libraries/DataEncoding.sol";
import {Diamond} from "../state-transition/libraries/Diamond.sol";
import {PriorityQueue} from "../state-transition/libraries/PriorityQueue.sol";
import {PriorityTree} from "../state-transition/libraries/PriorityTree.sol";
import {GatewayUpgradeFailed} from "./ZkSyncUpgradeErrors.sol";

import {IGatewayUpgrade} from "./IGatewayUpgrade.sol";
import {IL2ContractDeployer} from "../common/interfaces/IL2ContractDeployer.sol";
import {L1GatewayHelper} from "./L1GatewayHelper.sol";
import {IL1SharedBridgeLegacy} from "../bridge/interfaces/IL1SharedBridgeLegacy.sol";

import {IBridgehub} from "../bridgehub/IBridgehub.sol";

// solhint-disable-next-line gas-struct-packing
struct GatewayUpgradeEncodedInput {
Expand Down Expand Up @@ -45,40 +46,25 @@ contract GatewayUpgrade is BaseZkSyncUpgrade {
/// @param _proposedUpgrade The upgrade to be executed.
/// @dev Doesn't require any access-control restrictions as the contract is used in the delegate call.
function upgrade(ProposedUpgrade calldata _proposedUpgrade) public override returns (bytes32) {
GatewayUpgradeEncodedInput memory encodedInput = abi.decode(
(bytes memory l2TxDataStart, bytes memory l2TxDataFinish) = abi.decode(
_proposedUpgrade.postUpgradeCalldata,
(GatewayUpgradeEncodedInput)
(bytes, bytes)
);

bytes32 baseTokenAssetId = DataEncoding.encodeNTVAssetId(block.chainid, s.__DEPRECATED_baseToken);

s.baseTokenAssetId = baseTokenAssetId;
s.baseTokenAssetId = DataEncoding.encodeNTVAssetId(block.chainid, s.__DEPRECATED_baseToken);
s.priorityTree.setup(s.priorityQueue.getTotalPriorityTxs());
s.validators[encodedInput.oldValidatorTimelock] = false;
s.validators[encodedInput.newValidatorTimelock] = true;
IBridgehub(s.bridgehub).setLegacyBaseTokenAssetId(s.chainId);
ProposedUpgrade memory proposedUpgrade = _proposedUpgrade;

bytes memory gatewayUpgradeCalldata = abi.encode(
encodedInput.ctmDeployer,
encodedInput.fixedForceDeploymentsData,
L1GatewayHelper.getZKChainSpecificForceDeploymentsData(
s,
encodedInput.wrappedBaseTokenStore,
s.__DEPRECATED_baseToken
)
address l2LegacyBridge = IL1SharedBridgeLegacy(s.baseTokenBridge).l2BridgeAddress(s.chainId);
proposedUpgrade.l2ProtocolUpgradeTx.data = bytes.concat(
l2TxDataStart,
bytes32(uint256(uint160(l2LegacyBridge))),
l2TxDataFinish
);
encodedInput.forceDeployments[encodedInput.l2GatewayUpgradePosition].input = gatewayUpgradeCalldata;

proposedUpgrade.l2ProtocolUpgradeTx.data = abi.encodeCall(
IL2ContractDeployer.forceDeployOnAddresses,
(encodedInput.forceDeployments)
);

// slither-disable-next-line controlled-delegatecall
(bool success, ) = THIS_ADDRESS.delegatecall(abi.encodeCall(IGatewayUpgrade.upgradeExternal, proposedUpgrade));
if (!success) {
revert GatewayUpgradeFailed();
}
// solhint-disable-next-line gas-custom-errors
require(success, "GatewayUpgrade: upgrade failed");
return Diamond.DIAMOND_INIT_SUCCESS_RETURN_VALUE;
}

Expand Down
Loading

0 comments on commit 45cf28c

Please sign in to comment.