The L1ERC20Bridge::deposit function, which enables legacy deposits, introduces a vulnerability where user balances are deducted more than once. This occurs due to misaligned assumptions between the L1ERC20Bridge and the L1AssetRouter regarding token handling. Specifically, the L1ERC20Bridge debits the user's balance and transfers the amount to its contract balance. However, the subsequent call to L1AssetRouter::depositLegacyErc20Bridge erroneously attempts to debit the user's balance again, causing multiple deductions.
The protocol enable users to deposit through the legacy method by calling L1ERC20Bridge::deposit .
This function debits the user's deposited amount from their address, then calls L1AssetRouter::depositLegacyErc20Bridge which handle deposits from the legacy ERC20 bridge by converting them to the new bridge format and initiating the deposit through the bridgehub.
The issue is when L1ERC20Bridge::deposit is called, the depositor is first debited. The amount to deposit is withdrawn from the users balances and transferred to the L1ERC20Bridge contract balance.
Note that the L1ERC20Bridge contract anticipates the L1AssetRouter pulling these tokens from its balance, as evident by the approval line 230. Additionally, in L1AssetRouter::depositLegacyErc20Bridge, the asset router gives approval to the NativeTokenVault (the contract responsible for handling bridged assets) to move these tokens from its balance.
The issues:
Note that there are two issues (root causes) here
While L1AssetRouter assumes the tokens have already been sent to it balance, L1ERC20Bridge was also assuming depositLegacyErc20Bridge will pull the tokens from its balance, leading to a situation where the tokens remained in L1ERC20Bridge balance -- beyond the reach of NativeTokenVault.
Secondly, when _burn was called in L1AssetRouter::depositLegacyErc20Bridge, the original depositor address is passed in as the _originalCaller, instead of the contract actually holding the tokens to be burned. This lead to the users balance been debited again when the NativeTokenVault::bridgeBurn is finally called. The L1ERC20Bridge shouldn't have debited the user in the first place, they were still going to end up debited again down the call trace.
The vulnerability results in users being debited multiple times for the same deposit, leading to an incorrect reduction in their balances. This creates financial losses for users and undermines the trust in the system.
Manual review
Align Token Handling Assumptions: Ensure L1ERC20Bridge and L1AssetRouter have consistent assumptions about where tokens reside during the deposit process.
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.