From d7103f8954ff0dac48afd642de4d62ba56b7e543 Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Wed, 3 Apr 2024 08:20:59 +0200 Subject: [PATCH] set of fixes to the dev branch --- system-contracts/bootloader/bootloader.yul | 10 +++++++++- system-contracts/contracts/Compressor.sol | 4 ++-- system-contracts/contracts/L2BaseToken.sol | 4 ++-- system-contracts/contracts/interfaces/ICompressor.sol | 4 ++-- .../contracts/libraries/SystemContractHelper.sol | 6 +++--- .../contracts/libraries/SystemContractsCaller.sol | 2 +- system-contracts/contracts/precompiles/P256Verify.yul | 6 +++--- 7 files changed, 22 insertions(+), 14 deletions(-) diff --git a/system-contracts/bootloader/bootloader.yul b/system-contracts/bootloader/bootloader.yul index f669a66c7..c8859a7fa 100644 --- a/system-contracts/bootloader/bootloader.yul +++ b/system-contracts/bootloader/bootloader.yul @@ -1586,6 +1586,14 @@ object "Bootloader" { checkEnoughGas(gasLeft) let nearCallAbi := getNearCallABI(gasLeft) let gasBeforePostOp := gas() + + // It was expected that before this point various `isNotEnoughGasForPubdata` methods would ensure that the user + // has enough funds for pubdata. Now, we just subtract the leftovers from the user. + let spentOnPubdata := getErgsSpentForPubdata( + basePubdataSpent, + gasPerPubdata + ) + pop(ZKSYNC_NEAR_CALL_callPostOp( // Maximum number of gas that the postOp could spend nearCallAbi, @@ -1594,7 +1602,7 @@ object "Bootloader" { success, // Since the paymaster will be refunded with reservedGas, // it should know about it - safeAdd(gasLeft, reservedGas, "jkl"), + saturatingSub(safeAdd(gasLeft, reservedGas, "jkl"), spentOnPubdata), basePubdataSpent, reservedGas, gasPerPubdata diff --git a/system-contracts/contracts/Compressor.sol b/system-contracts/contracts/Compressor.sol index 640f022f5..f52c18ed4 100644 --- a/system-contracts/contracts/Compressor.sol +++ b/system-contracts/contracts/Compressor.sol @@ -44,7 +44,7 @@ contract Compressor is ICompressor, ISystemContract { function publishCompressedBytecode( bytes calldata _bytecode, bytes calldata _rawCompressedData - ) external payable onlyCallFromBootloader returns (bytes32 bytecodeHash) { + ) external onlyCallFromBootloader returns (bytes32 bytecodeHash) { unchecked { (bytes calldata dictionary, bytes calldata encodedData) = _decodeRawBytecode(_rawCompressedData); @@ -112,7 +112,7 @@ contract Compressor is ICompressor, ISystemContract { uint256 _enumerationIndexSize, bytes calldata _stateDiffs, bytes calldata _compressedStateDiffs - ) external payable onlyCallFrom(address(L1_MESSENGER_CONTRACT)) returns (bytes32 stateDiffHash) { + ) external onlyCallFrom(address(L1_MESSENGER_CONTRACT)) returns (bytes32 stateDiffHash) { // We do not enforce the operator to use the optimal, i.e. the minimally possible _enumerationIndexSize. // We do enforce however, that the _enumerationIndexSize is not larger than 8 bytes long, which is the // maximal ever possible size for enumeration index. diff --git a/system-contracts/contracts/L2BaseToken.sol b/system-contracts/contracts/L2BaseToken.sol index 5f806d08e..447143c3f 100644 --- a/system-contracts/contracts/L2BaseToken.sol +++ b/system-contracts/contracts/L2BaseToken.sol @@ -67,7 +67,7 @@ contract L2BaseToken is IBaseToken, ISystemContract { emit Mint(_account, _amount); } - /// @notice Initiate the ETH withdrawal, funds will be available to claim on L1 `finalizeEthWithdrawal` method. + /// @notice Initiate the withdrawal of the base token, funds will be available to claim on L1 `finalizeEthWithdrawal` method. /// @param _l1Receiver The address on L1 to receive the funds. function withdraw(address _l1Receiver) external payable override { uint256 amount = _burnMsgValue(); @@ -79,7 +79,7 @@ contract L2BaseToken is IBaseToken, ISystemContract { emit Withdrawal(msg.sender, _l1Receiver, amount); } - /// @notice Initiate the ETH withdrawal, with the sent message. The funds will be available to claim on L1 `finalizeEthWithdrawal` method. + /// @notice Initiate the withdrawal of the base token, with the sent message. The funds will be available to claim on L1 `finalizeEthWithdrawal` method. /// @param _l1Receiver The address on L1 to receive the funds. /// @param _additionalData Additional data to be sent to L1 with the withdrawal. function withdrawWithMessage(address _l1Receiver, bytes memory _additionalData) external payable override { diff --git a/system-contracts/contracts/interfaces/ICompressor.sol b/system-contracts/contracts/interfaces/ICompressor.sol index 5c1ee3d30..3062ea4f7 100644 --- a/system-contracts/contracts/interfaces/ICompressor.sol +++ b/system-contracts/contracts/interfaces/ICompressor.sol @@ -19,12 +19,12 @@ interface ICompressor { function publishCompressedBytecode( bytes calldata _bytecode, bytes calldata _rawCompressedData - ) external payable returns (bytes32 bytecodeHash); + ) external returns (bytes32 bytecodeHash); function verifyCompressedStateDiffs( uint256 _numberOfStateDiffs, uint256 _enumerationIndexSize, bytes calldata _stateDiffs, bytes calldata _compressedStateDiffs - ) external payable returns (bytes32 stateDiffHash); + ) external returns (bytes32 stateDiffHash); } diff --git a/system-contracts/contracts/libraries/SystemContractHelper.sol b/system-contracts/contracts/libraries/SystemContractHelper.sol index 7b6fb0236..82b3d3fd8 100644 --- a/system-contracts/contracts/libraries/SystemContractHelper.sol +++ b/system-contracts/contracts/libraries/SystemContractHelper.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.20; import {MAX_SYSTEM_CONTRACT_ADDRESS} from "../Constants.sol"; -import {CALLFLAGS_CALL_ADDRESS, CODE_ADDRESS_CALL_ADDRESS, EVENT_WRITE_ADDRESS, EVENT_INITIALIZE_ADDRESS, GET_EXTRA_ABI_DATA_ADDRESS, LOAD_CALLDATA_INTO_ACTIVE_PTR_CALL_ADDRESS, META_CODE_SHARD_ID_OFFSET, META_CALLER_SHARD_ID_OFFSET, META_SHARD_ID_OFFSET, META_AUX_HEAP_SIZE_OFFSET, META_HEAP_SIZE_OFFSET, META_GAS_PER_PUBDATA_BYTE_OFFSET, META_CALL_ADDRESS, PTR_CALLDATA_CALL_ADDRESS, PTR_ADD_INTO_ACTIVE_CALL_ADDRESS, PTR_SHRINK_INTO_ACTIVE_CALL_ADDRESS, PTR_PACK_INTO_ACTIVE_CALL_ADDRESS, PRECOMPILE_CALL_ADDRESS, SET_CONTEXT_VALUE_CALL_ADDRESS, TO_L1_CALL_ADDRESS} from "./SystemContractsCaller.sol"; +import {CALLFLAGS_CALL_ADDRESS, CODE_ADDRESS_CALL_ADDRESS, EVENT_WRITE_ADDRESS, EVENT_INITIALIZE_ADDRESS, GET_EXTRA_ABI_DATA_ADDRESS, LOAD_CALLDATA_INTO_ACTIVE_PTR_CALL_ADDRESS, META_CODE_SHARD_ID_OFFSET, META_CALLER_SHARD_ID_OFFSET, META_SHARD_ID_OFFSET, META_AUX_HEAP_SIZE_OFFSET, META_HEAP_SIZE_OFFSET, META_PUBDATA_PUBLISHED_OFFSET, META_CALL_ADDRESS, PTR_CALLDATA_CALL_ADDRESS, PTR_ADD_INTO_ACTIVE_CALL_ADDRESS, PTR_SHRINK_INTO_ACTIVE_CALL_ADDRESS, PTR_PACK_INTO_ACTIVE_CALL_ADDRESS, PRECOMPILE_CALL_ADDRESS, SET_CONTEXT_VALUE_CALL_ADDRESS, TO_L1_CALL_ADDRESS} from "./SystemContractsCaller.sol"; uint256 constant UINT32_MASK = type(uint32).max; uint256 constant UINT64_MASK = type(uint64).max; @@ -224,9 +224,9 @@ library SystemContractHelper { /// that a single byte sent to L1 as pubdata costs. /// @notice NOTE: The behavior of this function will experience a breaking change in 2024. /// @param meta Packed representation of the ZkSyncMeta. - /// @return pubdataPublished The current price in gas per pubdata byte. + /// @return pubdataPublished The amount of pubdata published in the system so far. function getPubdataPublishedFromMeta(uint256 meta) internal pure returns (uint32 pubdataPublished) { - pubdataPublished = uint32(extractNumberFromMeta(meta, META_GAS_PER_PUBDATA_BYTE_OFFSET, 32)); + pubdataPublished = uint32(extractNumberFromMeta(meta, META_PUBDATA_PUBLISHED_OFFSET, 32)); } /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the number of the current size diff --git a/system-contracts/contracts/libraries/SystemContractsCaller.sol b/system-contracts/contracts/libraries/SystemContractsCaller.sol index 89f8e14f7..d964fbbe7 100644 --- a/system-contracts/contracts/libraries/SystemContractsCaller.sol +++ b/system-contracts/contracts/libraries/SystemContractsCaller.sol @@ -38,7 +38,7 @@ address constant MULTIPLICATION_HIGH_ADDRESS = address((1 << 16) - 26); address constant GET_EXTRA_ABI_DATA_ADDRESS = address((1 << 16) - 27); // All the offsets are in bits -uint256 constant META_GAS_PER_PUBDATA_BYTE_OFFSET = 0 * 8; +uint256 constant META_PUBDATA_PUBLISHED_OFFSET = 0 * 8; uint256 constant META_HEAP_SIZE_OFFSET = 8 * 8; uint256 constant META_AUX_HEAP_SIZE_OFFSET = 12 * 8; uint256 constant META_SHARD_ID_OFFSET = 28 * 8; diff --git a/system-contracts/contracts/precompiles/P256Verify.yul b/system-contracts/contracts/precompiles/P256Verify.yul index 0af5d99c6..bf20e54be 100644 --- a/system-contracts/contracts/precompiles/P256Verify.yul +++ b/system-contracts/contracts/precompiles/P256Verify.yul @@ -73,7 +73,7 @@ object "P256Verify" { 0, // input offset in words 5, // input length in words (the signed digest, r, s, x, y) 0, // output offset in words - 1, // output length in words (success) + 2, // output length in words (internalSuccess, isValid) 0 // No special meaning, secp256r1 circuit doesn't check this value ) let gasToPay := P256_VERIFY_GAS_COST() @@ -89,8 +89,8 @@ object "P256Verify" { default { // The circuits might write `0` to the memory, while providing `internalSuccess` as `1`, so // we double check here. - let writtenValue := mload(32) - if eq(writtenValue, 0) { + let isValid := mload(32) + if eq(isValid, 0) { return(0, 0) }