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.