`SystemContext::getCurrentPubdataSpent()` incorrectly calculates gas fees due to assumption of the gas per pubdata being the same as the amount of pubdata already published
Audit: 2024-03-zksync-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-03-zksync/blob/4f0ba34f34a864c354c7e8c47643ed8f4a250e13/code/system-contracts/contracts/SystemContext.sol#L117-L121
https://github.com/code-423n4/2024-03-zksync/blob/4f0ba34f34a864c354c7e8c47643ed8f4a250e13/code/system-contracts/contracts/libraries/SystemContractHelper.sol#L279-L288
https://github.com/code-423n4/2024-03-zksync/blob/4f0ba34f34a864c354c7e8c47643ed8f4a250e13/code/system-contracts/contracts/libraries/SystemContractHelper.sol#L227-L229
https://github.com/code-423n4/2024-03-zksync/blob/4f0ba34f34a864c354c7e8c47643ed8f4a250e13/code/system-contracts/bootloader/bootloader.yul#L2709


# Vulnerability details


## Proof of Concept

Take a look at https://github.com/code-423n4/2024-03-zksync/blob/4f0ba34f34a864c354c7e8c47643ed8f4a250e13/code/system-contracts/contracts/SystemContext.sol#L117-L121

```solidity
    function getCurrentPubdataSpent() public view returns (uint256) {
        uint256 pubdataPublished = SystemContractHelper.getZkSyncMeta().pubdataPublished;
        return pubdataPublished > basePubdataSpent ? pubdataPublished - basePubdataSpent : 0;
    }

```

The above is one of the instances where a check for how much of the pubdata has been spent, evidently it makes a query to `SystemContractHelper.getZkSyncMeta().pubdataPublished` which is implemented here https://github.com/code-423n4/2024-03-zksync/blob/4f0ba34f34a864c354c7e8c47643ed8f4a250e13/code/system-contracts/contracts/libraries/SystemContractHelper.sol#L279-L288

```solidity
    function getZkSyncMeta() internal view returns (ZkSyncMeta memory meta) {
        uint256 metaPacked = getZkSyncMetaBytes();
        meta.pubdataPublished = getPubdataPublishedFromMeta(metaPacked);
         //@audit
        //..snip
    }

```

And https://github.com/code-423n4/2024-03-zksync/blob/4f0ba34f34a864c354c7e8c47643ed8f4a250e13/code/system-contracts/contracts/libraries/SystemContractHelper.sol#L227-L229

```solidity
    function getPubdataPublishedFromMeta(uint256 meta) internal pure returns (uint32 pubdataPublished) {
        pubdataPublished = uint32(extractNumberFromMeta(meta, META_GAS_PER_PUBDATA_BYTE_OFFSET, 32));
    }
```

Case is that this function instead returns the previous implemented `gasPerPubdata` and not the pubdata that's been published, keep in mind that the value returned from this is what's been used here `  return pubdataPublished > basePubdataSpent ? pubdataPublished - basePubdataSpent : 0;` which indicates that protocol wrongly attempts to subtract from the "price" of gas per `pubdata` and not the amount of `pubdata` already "published", a hint on how the correct implementation is can be seen from [the previous codebase](https://github.com/code-423n4/2023-10-zksync/blob/26547a90d569559ef5c80ff8c523010134e84a71/code/system-contracts/contracts/L1Messenger.sol#L138-L140), which indicates that this value represents the cost of one pubdata byte and not the amount of pubdata already spent as is being represented in th