Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/kl-factory' into bh-shared-bridg…
Browse files Browse the repository at this point in the history
…e-foundry-testing
  • Loading branch information
benceharomi committed Jan 24, 2024
2 parents 63031ba + 1c424b0 commit 6c95526
Show file tree
Hide file tree
Showing 38 changed files with 620 additions and 535 deletions.
2 changes: 2 additions & 0 deletions l1-contracts/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ CHAIN_ETH_NETWORK=hardhat
CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT=72000000
CONTRACTS_DEPLOY_L2_BRIDGE_COUNTERPART_GAS_LIMIT=10000000
ETH_CLIENT_WEB3_URL=http://127.0.0.1:8545
CHAIN_ETH_ZKSYNC_NETWORK_ID=270
CONTRACTS_BRIDGEHUB_PROXY_ADDR=0x0000000000000000000000000000000000000000
CONTRACTS_BRIDGEHUB_IMPL_ADDR=0x0000000000000000000000000000000000000000
CONTRACTS_STATE_TRANSITION_PROXY_ADDR=0x0000000000000000000000000000000000000000
Expand All @@ -28,3 +29,4 @@ CONTRACTS_L1_ALLOW_LIST_ADDR=0x0000000000000000000000000000000000000000
CONTRACTS_CREATE2_FACTORY_ADDR=0x0000000000000000000000000000000000000000
CONTRACTS_VALIDATOR_TIMELOCK_ADDR=0x0000000000000000000000000000000000000000
CONTRACTS_VALIDATOR_TIMELOCK_EXECUTION_DELAY=0
ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR=0x0000000000000000000000000000000000000000
26 changes: 14 additions & 12 deletions l1-contracts/contracts/bridge/L1ERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ contract L1ERC20Bridge is
mapping(uint256 => bool) internal bridgeImplTxSucceeded;

/// @dev A mapping chainId => bridgeImplTxHash. Used to check the deploy transaction of the l2Bridge Implementation (which depends on its place in the priority queue).
mapping(uint256 => bytes32) internal bridgeImplDeployOnL2TxHash;
mapping(uint256 => bytes32) public bridgeImplDeployOnL2TxHash;

/// @dev A mapping chainId => bridgeProxyTxHash. Used to check the deploy transaction of the l2Bridge Proxy (which depends on its place in the priority queue).
mapping(uint256 => bytes32) public bridgeProxyDeployOnL2TxHash;
Expand All @@ -105,8 +105,9 @@ contract L1ERC20Bridge is
/// @dev Used to indicate that L2 -> L1 message was already processed
mapping(uint256 => mapping(uint256 => mapping(uint256 => bool))) public isWithdrawalFinalizedShared;

/// @dev A mapping chainId => keccak256(account, tokenAddress, amount) => L2 deposit transaction hash
/// @dev Used for saving the number of deposited funds, to claim them in case the deposit transaction will fail
/// @dev A mapping chainId => L2 deposit transaction hash => keccak256(account, tokenAddress, amount)
/// @dev Used for saving the number of deposited funds, to claim them in case the deposit transaction will fail.
/// @dev the l2TxHash is unique, as it is determined by the contracts, while dataHash is not, so we that is the output.
mapping(uint256 => mapping(bytes32 => bytes32)) public depositHappened;

/// @dev used for extra security until hyperbridging is implemented.
Expand Down Expand Up @@ -418,6 +419,7 @@ contract L1ERC20Bridge is
/// 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 _mintValue The amount of baseTokens to be minted on L2. In this case Eth
/// @param _amount The total amount of tokens to be bridged
/// @param _l2TxGasLimit The L2 gas limit to be used in the corresponding L2 transaction
/// @param _l2TxGasPerPubdataByte The gasPerPubdataByteLimit to be used in the corresponding L2 transaction
Expand Down Expand Up @@ -480,7 +482,7 @@ contract L1ERC20Bridge is

// Save the deposited amount to claim funds on L1 if the deposit failed on L2
bytes32 txDataHash = keccak256(abi.encode(msg.sender, _l1Token, _amount));
depositHappened[_chainId][txDataHash] = l2TxHash;
depositHappened[_chainId][l2TxHash] = txDataHash;

emit DepositInitiatedSharedBridge(_chainId, txDataHash, msg.sender, _l2Receiver, _l1Token, _amount);
if (_chainId == ERA_CHAIN_ID) {
Expand Down Expand Up @@ -606,8 +608,8 @@ contract L1ERC20Bridge is
bytes32 _txDataHash,
bytes32 _txHash
) external override onlyBridgehub {
require(depositHappened[_chainId][_txDataHash] == 0x00, "EB tx hap");
depositHappened[_chainId][_txDataHash] = _txHash;
require(depositHappened[_chainId][_txHash] == 0x00, "EB tx hap");
depositHappened[_chainId][_txHash] = _txDataHash;
emit BridgehubDepositFinalized(_chainId, _txDataHash, _txHash);
}

Expand Down Expand Up @@ -710,7 +712,7 @@ contract L1ERC20Bridge is
if ((_chainId == ERA_CHAIN_ID) && usingLegacyDepositAmountStorageVar) {
delete depositAmountEra[_depositSender][_l1Token][_l2TxHash];
} else {
delete depositHappened[_chainId][txDataHash];
delete depositHappened[_chainId][_l2TxHash];
}
if (!hyperbridgingEnabled[_chainId]) {
// check that the chain has sufficient balance
Expand Down Expand Up @@ -744,15 +746,15 @@ contract L1ERC20Bridge is
usingLegacyDepositAmountStorageVar = true;
require(_amount == amount, "EB w amnt");
} else {
bytes32 txHash;
bytes32 dataHash;
{
txHash = depositHappened[_chainId][_txDataHash];
dataHash = depositHappened[_chainId][_l2TxHash];
}
require(txHash == _l2TxHash, "EB: d.it not hap");
require(dataHash == _txDataHash, "EB: d.it not hap");
}
} else {
bytes32 txHash = depositHappened[_chainId][_txDataHash];
require(txHash == _l2TxHash, "EB w d.it 2"); // wrong/invalid deposit
bytes32 dataHash = depositHappened[_chainId][_l2TxHash];
require(dataHash == _txDataHash, "EB w d.it 2"); // wrong/invalid deposit
}
}

Expand Down
17 changes: 10 additions & 7 deletions l1-contracts/contracts/bridge/L1WethBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,15 @@ contract L1WethBridge is IL1Bridge, ReentrancyGuard, Initializable, Ownable2Step
mapping(uint256 => address) internal l2WethPotentialAddress;

/// @dev A mapping chainId => bridgeImplTxHash. Used to check the deploy transaction (which depends on its place in the priority queue).
mapping(uint256 => bytes32) internal bridgeImplDeployOnL2TxHash;
mapping(uint256 => bytes32) public bridgeImplDeployOnL2TxHash;

/// @dev we have to record if the bridgeImplTx succeeded
mapping(uint256 => bool) internal bridgeImplTxSucceeded;

/// @dev A mapping chainId => bridgeProxyTxHash. Used to check the deploy transaction (which depends on its place in the priority queue).
mapping(uint256 => bytes32) public bridgeProxyDeployOnL2TxHash;

/// @dev A mapping chainId => keccak256(account, amount) => L2 deposit transaction hash
/// @dev A mapping chainId => L2 deposit transaction hash => keccak256(account, amount)
/// @dev Used for saving the number of deposited funds, to claim them in case the deposit transaction will fail
/// @dev only used when it is not the base token, as then it is sent to refund recipient
mapping(uint256 => mapping(bytes32 => bytes32)) internal depositHappened;
Expand Down Expand Up @@ -544,8 +544,8 @@ contract L1WethBridge is IL1Bridge, ReentrancyGuard, Initializable, Ownable2Step
bytes32 _txDataHash,
bytes32 _txHash
) external override onlyBridgehub {
require(depositHappened[_chainId][_txDataHash] == 0x00, "L1WETHBridge: tx already happened");
depositHappened[_chainId][_txDataHash] = _txHash;
require(depositHappened[_chainId][_txHash] == 0x00, "L1WETHBridge: tx already happened");
depositHappened[_chainId][_txHash] = _txDataHash;
emit BridgehubDepositFinalized(_chainId, _txDataHash, _txHash);
}

Expand Down Expand Up @@ -587,13 +587,16 @@ contract L1WethBridge is IL1Bridge, ReentrancyGuard, Initializable, Ownable2Step
);
require(proofValid, "L1WB: Invalid L2 transaction status proof");

bytes32 txHash = depositHappened[_chainId][keccak256(abi.encode(_depositSender, _amount))];
require(((_amount > 0) && (txHash == _l2TxHash)), "L1WB: _amount is zero or deposit did not happen");
bytes32 txDataHash = depositHappened[_chainId][_l2TxHash];
require(
((_amount > 0) && (txDataHash == keccak256(abi.encode(_depositSender, _amount)))),
"L1WB: _amount is zero or deposit did not happen"
);
if (!hyperbridgingEnabled[_chainId]) {
require(chainBalance[_chainId] >= _amount, "L1WB: chainBalance is too low");
chainBalance[_chainId] -= _amount;
}
delete depositHappened[_chainId][keccak256(abi.encode(_depositSender, _amount))];
delete depositHappened[_chainId][_l2TxHash];

// Withdraw funds
// Wrap ETH to WETH tokens (smart contract address receives the equivalent _amount of WETH)
Expand Down
5 changes: 3 additions & 2 deletions l1-contracts/contracts/dev-contracts/test/AdminFacetTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import "../../state-transition/chain-deps/facets/Admin.sol";
contract AdminFacetTest is AdminFacet {
constructor() {
s.governor = msg.sender;
s.stateTransitionManager = msg.sender;
}

function getPorterAvailability() external view returns (bool) {
return s.zkPorterIsAvailable;
}

function isValidator(address _address) external view returns (bool) {
return s.validators[_address];
function isValidator(address _validator) external view returns (bool) {
return s.validators[_validator];
}

function getPriorityTxMaxGasLimit() external view returns (uint256) {
Expand Down
11 changes: 11 additions & 0 deletions l1-contracts/contracts/dev-contracts/test/DummyAdminFacet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.20;

import "../../state-transition/chain-deps/facets/Base.sol";

contract DummyAdminFacet is ZkSyncStateTransitionBase {
function dummySetValidator(address _validator) external {
s.validators[_validator] = true;
}
}
37 changes: 33 additions & 4 deletions l1-contracts/contracts/dev-contracts/test/DummyExecutor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ contract DummyExecutor is IExecutor {
_;
}

function getGovernor() external view returns (address) {
return owner;
}

/// @notice Removing txs from the priority queue
function removePriorityQueueFront(uint256 _index) external {
// KL todo
Expand All @@ -55,7 +59,7 @@ contract DummyExecutor is IExecutor {
function commitBatches(
StoredBatchInfo calldata _lastCommittedBatchData,
CommitBatchInfo[] calldata _newBatchesData
) external {
) public {
require(!shouldRevertOnCommitBatches, "DummyExecutor: shouldRevertOnCommitBatches");
require(
_lastCommittedBatchData.batchNumber == getTotalBatchesCommitted,
Expand All @@ -70,11 +74,19 @@ contract DummyExecutor is IExecutor {
getTotalBatchesCommitted += batchesLength;
}

function commitBatchesSharedBridge(
uint256,
StoredBatchInfo calldata _lastCommittedBatchData,
CommitBatchInfo[] calldata _newBatchesData
) external {
commitBatches(_lastCommittedBatchData, _newBatchesData);
}

function proveBatches(
StoredBatchInfo calldata _prevBatch,
StoredBatchInfo[] calldata _committedBatches,
ProofInput calldata
) external {
) public {
require(!shouldRevertOnProveBatches, "DummyExecutor: shouldRevertOnProveBatches");
require(_prevBatch.batchNumber == getTotalBatchesVerified, "DummyExecutor: Invalid previous batch number");

Expand All @@ -91,7 +103,16 @@ contract DummyExecutor is IExecutor {
);
}

function executeBatches(StoredBatchInfo[] calldata _batchesData) external {
function proveBatchesSharedBridge(
uint256,
StoredBatchInfo calldata _prevBatch,
StoredBatchInfo[] calldata _committedBatches,
ProofInput calldata _proof
) external {
proveBatches(_prevBatch, _committedBatches, _proof);
}

function executeBatches(StoredBatchInfo[] calldata _batchesData) public {
require(!shouldRevertOnExecuteBatches, "DummyExecutor: shouldRevertOnExecuteBatches");
uint256 nBatches = _batchesData.length;
for (uint256 i = 0; i < nBatches; ++i) {
Expand All @@ -104,7 +125,11 @@ contract DummyExecutor is IExecutor {
);
}

function revertBatches(uint256 _newLastBatch) external {
function executeBatchesSharedBridge(uint256, StoredBatchInfo[] calldata _batchesData) external {
executeBatches(_batchesData);
}

function revertBatches(uint256 _newLastBatch) public {
require(
getTotalBatchesCommitted > _newLastBatch,
"DummyExecutor: The last committed batch is less than new last batch"
Expand All @@ -117,6 +142,10 @@ contract DummyExecutor is IExecutor {
getTotalBatchesCommitted = newTotalBatchesCommitted;
}

function revertBatchesSharedBridge(uint256, uint256 _newLastBatch) external {
revertBatches(_newLastBatch);
}

/// @notice Returns larger of two values
function _maxU256(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? b : a;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.20;

import "../../state-transition/StateTransitionManager.sol";

/// @title DummyExecutor
/// @notice A test smart contract implementing the IExecutor interface to simulate Executor behavior for testing purposes.
contract DummyStateTransitionManager is StateTransitionManager {
/// @notice Constructor
constructor() StateTransitionManager(address(0)) {}

function setStateTransition(uint256 _chainId, address _stateTransition) external {
stateTransition[_chainId] = _stateTransition;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import {L2CanonicalTransaction} from "../common/Messaging.sol";

/// @notice Struct that holds all data needed for initializing STM Proxy.
/// @dev We use struct instead of raw parameters in `initialize` function to prevent "Stack too deep" error
/// @param _governor address who can manage critical updates in the contract
/// @param _admin address who can manage non-critical updates in the contract
/// @param _governor address who can manage non-critical updates in the contract
/// @param _validatorTimelock address that serves as consensus, i.e. can submit blocks to be processed
/// @param _genesisBatchHash Batch hash of the genesis (initial) batch
/// @param _genesisIndexRepeatedStorageChanges The serial number of the shortcut storage key for genesis batch
/// @param _genesisBatchCommitment The zk-proof commitment for the genesis batch
struct StateTransitionManagerInitializeData {
address governor;
address validatorTimelock;
address genesisUpgrade;
bytes32 genesisBatchHash;
uint64 genesisIndexRepeatedStorageChanges;
Expand Down Expand Up @@ -48,6 +49,12 @@ interface IStateTransitionManager {

function initialize(StateTransitionManagerInitializeData calldata _initalizeData) external;

function setInitialCutHash(Diamond.DiamondCutData calldata _diamondCut) external;

function setValidatorTimelock(address _validatorTimelock) external;

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

/// @notice
function createNewChain(
uint256 _chainId,
Expand Down
19 changes: 16 additions & 3 deletions l1-contracts/contracts/state-transition/StateTransitionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {IExecutor} from "./chain-interfaces/IExecutor.sol";
import {IStateTransitionManager, StateTransitionManagerInitializeData} from "./IStateTransitionManager.sol";
import {ISystemContext} from "./l2-deps/ISystemContext.sol";
import {IZkSyncStateTransition} from "./chain-interfaces/IZkSyncStateTransition.sol";
import {L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, L2_BOOTLOADER_ADDRESS} from "../common/L2ContractAddresses.sol";
import {L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, L2_FORCE_DEPLOYER_ADDR} from "../common/L2ContractAddresses.sol";
import {L2CanonicalTransaction} from "../common/Messaging.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {ProposedUpgrade} from "../upgrades/BaseZkSyncUpgrade.sol";
Expand Down Expand Up @@ -41,6 +41,9 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own
/// @dev current protocolVersion
uint256 public protocolVersion;

/// @dev validatorTimelock contract address, used to setChainId
address public validatorTimelock;

/// @dev Stored cutData for upgrade diamond cut. protocolVersion => cutHash
mapping(uint256 => bytes32) public upgradeCutHash;

Expand Down Expand Up @@ -71,6 +74,10 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own
_;
}

function getChainGovernor(uint256 _chainId) external view override returns (address) {
return IZkSyncStateTransition(stateTransition[_chainId]).getGovernor();
}

/// @dev initialize
function initialize(
StateTransitionManagerInitializeData calldata _initializeData
Expand All @@ -80,6 +87,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own

genesisUpgrade = _initializeData.genesisUpgrade;
protocolVersion = _initializeData.protocolVersion;
validatorTimelock = _initializeData.validatorTimelock;

// We need to initialize the state hash because it is used in the commitment of the next batch
IExecutor.StoredBatchInfo memory batchZero = IExecutor.StoredBatchInfo(
Expand All @@ -101,6 +109,11 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own
assert(L2_TO_L1_LOG_SERIALIZE_SIZE != 2 * 32);
}

/// @dev set validatorTimelock. Cannot do it an initialization, as validatorTimelock is deployed after STM
function setValidatorTimelock(address _validatorTimelock) external onlyOwner {
validatorTimelock = _validatorTimelock;
}

/// @dev set initial cutHash
function setInitialCutHash(Diamond.DiamondCutData calldata _diamondCut) external onlyOwner {
initialCutHash = keccak256(abi.encode(_diamondCut));
Expand Down Expand Up @@ -139,7 +152,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own

L2CanonicalTransaction memory l2ProtocolUpgradeTx = L2CanonicalTransaction({
txType: SYSTEM_UPGRADE_L2_TX_TYPE,
from: uint256(uint160(L2_BOOTLOADER_ADDRESS)),
from: uint256(uint160(L2_FORCE_DEPLOYER_ADDR)),
to: uint256(uint160(L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR)),
gasLimit: $(PRIORITY_TX_MAX_GAS_LIMIT),
gasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA,
Expand Down Expand Up @@ -210,7 +223,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own
bytes32(uint256(uint160(address(this)))),
bytes32(uint256(protocolVersion)),
bytes32(uint256(uint160(_governor))),
bytes32(uint256(uint160(_governor))),
bytes32(uint256(uint160(validatorTimelock))),
bytes32(uint256(uint160(_baseToken))),
bytes32(uint256(uint160(_baseTokenBridge))),
bytes32(storedBatchZero),
Expand Down
Loading

0 comments on commit 6c95526

Please sign in to comment.