MondrianWallet2::payForTransaction
lacks access control, allowing a malicious actor to block a transaction by draining the contract prior to validation.Description: According to the ZKsync documentation, the payForTransaction
function is meant to be called only by the Bootloader to collect fees necessary to execute transactions.
However, because an access control is missing in MondrianWallet2::payForTransaction
anyone can call the function. There is also no check on how often the function is called.
This allows a malicious actor to observe the transaction in the mempool and use its data to repeatedly call payForTransaction. It results in moving funds from MondrianWallet2
to the ZKSync Bootloader.
Impact: When funds are moved from the MondrianWallet2
to the ZKSync Bootloader, MondrianWallet2::validateTransaction
will fail due to lack of funds. Also, when the bootloader itself eventually calls payForTransaction
to retrieve funds, this function will fail.
In effect, the lack of access controls on MondrianWallet2::payForTransaction
allows for any transaction to be blocked by a malicious user.
Please note that there is a refund of unused fees on ZKsync. As such, it is likely that MondrianWallet2
will eventually receive a refund of its fees. However, it is likely a refund will only happen after the transaction has been declined.
Proof of Concept:
Due to limits in the toolchain used (foundry) to test the ZKSync blockchain, it was not possible to obtain a fine grained understanding of how the bootloader goes through the life cycle of a 113 type transaction. It made it impossible to create a true Proof of Concept of this vulnerability. What follows is as close as possible approximation using foundry's standard test suite.
The sequence:
Normal user A creates a transaction.
Malicious user B observes the transaction.
Malicious user B calls MondrianWallet2::payForTransaction
until mondrianWallet2.balance < transaction.maxFeePerGas * transaction.gasLimit
.
The bootloader calls MondrianWallet::validateTransaction
.
MondrianWallet::validateTransaction
fails because of lack of funds.
Place the following in ModrianWallet2Test.t.sol
.
Recommended Mitigation: Add an access control to the MondrianWallet2::payForTransaction
function, allowing only the bootloader to call the function.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.