Closed c4-bot-2 closed 6 months ago
saxenism (sponsor) disputed
This is indeed a good finding, but we consider this out of scope since l1 weth bridge is not deployed on mainnet.
The Warden details a misbehavior that might arise as part of a migration of the legacy L1WethBridge
, however, the Sponsor has specified this contract has not been deployed.
I could not find any online evidence that the L1WethBridge
was ever deployed or in operation, and several breaking changes have been cataloged in the contest's changelog alongside the deprecation of the L1WethBridge
(incorrectly spelled as L1WethBridge
).
In addition to this, the official list of main-net deployments that was available at the time the contest initiated did not list L1WethBridge
as deployed based on the publicly available GitHub repository: https://github.com/matter-labs/zksync-web-era-docs/blob/b6fef08381e92c2b8b5adea6beb3ed5431c54f79/docs/build/quick-start/useful-address.md
I appreciate the Warden's thoroughness and unique approach demonstrated in this finding, but I cannot accept it as a valid vulnerability as it is practically inapplicable.
alex-ppg marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2024-03-zksync/blob/4f0ba34f34a864c354c7e8c47643ed8f4a250e13/code/contracts/ethereum/contracts/bridge/L1SharedBridge.sol#L443-L447
Vulnerability details
Impact
A user might not be able to withdraw WETH/ETH on L1 with legacy l2Batchnumber, resulting in ETH permanently locked in L1SharedBridge.sol.
The new Mailbox is not always backward compatible.
Proof of Concept
New Mailbox and L1SharedBridge are intended to be backward compatible. But the current implementation of Mailbox.sol and L1SharedBridge.sol' s withdrawal flow might cause certain legacy WETH deposits to be locked when withdrawn.
Suppose a user deposited WETH before the upgrade through old L1WETHBridge.sol. Now user initiated the withdrawal of WETH from old L2WETHBridge.sol before ERA upgrade.
(1) Since upgrade hasn't started or is about to start, user would still interact with the old L2WETHBridge.sol
withdraw()
, which burns user's L2Weth for ETH and send a ETH withdraw throughL2_ETH_ADDRESS.withdrawWithMessage{value: _amount}(l1Bridge, wethMessage);
. Note that this setl1Bridge
as the l1 receiver (old L1WETHbridge.sol). The user designated_l1Receiver
is part ofwethMessage
.(2) Now if L1 ERA upgrade hasn't started yet, the user will still call L1WethBrdige.sol's
finalizeWithdrawal()
to withdraw WETH. However, if L1 ERA-upgrade settles first before the user'sfinalizeWithdrawal()
call. L1WethBridge.sol'sfinalizeWithdrawal()
tx will call the new mailbox'sfinalizeEthWithdrawal()
function.The problem occurs here: Although the new Mailbox.sol maintains
finalizeEthWithdrawal()
, this won't be backward compatible with a legacy WETH withdrawal flow.The new
finalizeEthWithdrawal()
will call L1SharedBridge'sfinalizeWithdrawal()
. L1SharedBridge will send ETH tol1Reciver
(L1WethBridge address, Not the user's address). However, the ETH transfer will revert due to L1WethBridge.sol will not recognize L1SharedBridge.sol's address and revert in thereceive()
fallback.(https://github.com/code-423n4/2024-03-zksync/blob/4f0ba34f34a864c354c7e8c47643ed8f4a250e13/code/contracts/ethereum/contracts/state-transition/chain-deps/facets/Mailbox.sol#L186)
(https://github.com/code-423n4/2024-03-zksync/blob/4f0ba34f34a864c354c7e8c47643ed8f4a250e13/code/contracts/ethereum/contracts/bridge/L1SharedBridge.sol#L443-L447)
Note: if the user calls
finalizeEthWithdrawal()
directly on the new Mailbox.sol, this will also revert due to the same reason above.Because the old L2WethBridge.sol will code L1Wethbridge.sol as L1receiver, any attempts of Weth withdrawal on L2 close to or during ERA upgrade might result in ETH permanently locked on L1SharedBridge.sol. User will lose funds.
Tools Used
Manual
Recommended Mitigation Steps
since the new Mailbox's intended to be backward compatible and there will be legacy Weth withdrawal tx, it needs to be ensured that on-going users' legacy weth withdrawal tx will not lock funds on L1SharedBridge.
Consider refactoring Mailbox's
finalizeEthWithdrawal()
to be compatible with the legacy Weth withdrawal flow.Assessed type
Other