diff --git a/contracts/zksync/l1-contracts/bridge/L1ERC20Bridge.sol b/contracts/zksync/l1-contracts/bridge/L1ERC20Bridge.sol index 6998461..e7ed5ec 100644 --- a/contracts/zksync/l1-contracts/bridge/L1ERC20Bridge.sol +++ b/contracts/zksync/l1-contracts/bridge/L1ERC20Bridge.sol @@ -71,6 +71,7 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard { /// @notice _factoryDeps[0] == a raw bytecode of L2 bridge implementation /// @notice _factoryDeps[1] == a raw bytecode of proxy that is used as L2 bridge /// @notice _factoryDeps[2] == a raw bytecode of token proxy + /// @param _factoryDepByteCodeHashes A list of raw bytecode sha256 hashes that are needed for deployment of the L2 bridge /// @param _l2TokenBeacon Pre-calculated address of the L2 token upgradeable beacon /// @notice At the time of the function call, it is not yet deployed in L2, but knowledge of its address /// @notice is necessary for determining L2 token address by L1 address, see `l2TokenAddress(address)` function @@ -80,6 +81,7 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard { /// @param _deployBridgeProxyFee How much of the sent value should be allocated to deploying the L2 bridge proxy function initialize( bytes[] calldata _factoryDeps, + bytes32[] calldata _factoryDepByteCodeHashes, address _l2TokenBeacon, address _governor, uint256 _deployBridgeImplementationFee, @@ -89,13 +91,23 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard { require(_governor != address(0), "nh"); // We are expecting to see the exact three bytecodes that are needed to initialize the bridge require(_factoryDeps.length == 3, "mk"); + require(_factoryDeps.length == _factoryDepByteCodeHashes.length, "mg"); // The caller miscalculated deploy transactions fees require(msg.value == _deployBridgeImplementationFee + _deployBridgeProxyFee, "fee"); - l2TokenProxyBytecodeHash = L2ContractHelper.hashL2Bytecode(_factoryDeps[2]); + l2TokenProxyBytecodeHash = L2ContractHelper.hashL2Bytecode( + _factoryDeps[2].length, + _factoryDepByteCodeHashes[2] + ); l2TokenBeacon = _l2TokenBeacon; - bytes32 l2BridgeImplementationBytecodeHash = L2ContractHelper.hashL2Bytecode(_factoryDeps[0]); - bytes32 l2BridgeProxyBytecodeHash = L2ContractHelper.hashL2Bytecode(_factoryDeps[1]); + bytes32 l2BridgeImplementationBytecodeHash = L2ContractHelper.hashL2Bytecode( + _factoryDeps[0].length, + _factoryDepByteCodeHashes[0] + ); + bytes32 l2BridgeProxyBytecodeHash = L2ContractHelper.hashL2Bytecode( + _factoryDeps[1].length, + _factoryDepByteCodeHashes[1] + ); // Deploy L2 bridge implementation contract address bridgeImplementationAddr = BridgeInitializationHelper.requestDeployTransaction( diff --git a/contracts/zksync/l1-contracts/common/libraries/L2ContractHelper.sol b/contracts/zksync/l1-contracts/common/libraries/L2ContractHelper.sol index 2ca65e5..98ca680 100644 --- a/contracts/zksync/l1-contracts/common/libraries/L2ContractHelper.sol +++ b/contracts/zksync/l1-contracts/common/libraries/L2ContractHelper.sol @@ -12,20 +12,24 @@ library L2ContractHelper { bytes32 private constant CREATE2_PREFIX = keccak256("zksyncCreate2"); /// @notice Validate the bytecode format and calculate its hash. - /// @param _bytecode The bytecode to hash. + /// @param _bytecodeLength The bytecode length. + /// @param _bytecodeHash The bytecode hash. /// @return hashedBytecode The 32-byte hash of the bytecode. /// Note: The function reverts the execution if the bytecode has non expected format: /// - Bytecode bytes length is not a multiple of 32 /// - Bytecode bytes length is not less than 2^21 bytes (2^16 words) /// - Bytecode words length is not odd - function hashL2Bytecode(bytes memory _bytecode) internal pure returns (bytes32 hashedBytecode) { + function hashL2Bytecode( + uint256 _bytecodeLength, + bytes32 _bytecodeHash + ) internal pure returns (bytes32 hashedBytecode) { // Note that the length of the bytecode must be provided in 32-byte words. - require(_bytecode.length % 32 == 0, "pq"); + require(_bytecodeLength % 32 == 0, "pq"); - uint256 bytecodeLenInWords = _bytecode.length / 32; + uint256 bytecodeLenInWords = _bytecodeLength / 32; require(bytecodeLenInWords < 2 ** 16, "pp"); // bytecode length must be less than 2^16 words require(bytecodeLenInWords % 2 == 1, "ps"); // bytecode length in words must be odd - hashedBytecode = sha256(_bytecode) & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; + hashedBytecode = _bytecodeHash & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // Setting the version of the hash hashedBytecode = (hashedBytecode | bytes32(uint256(1 << 248))); // Setting the length