Platform: Code4rena
Start Date: 02/10/2023
Pot Size: $1,100,000 USDC
Total HM: 28
Participants: 64
Period: 21 days
Judge: GalloDaSballo
Total Solo HM: 13
Id: 292
League: ETH
Rank: 52/64
Findings: 1
Award: $273.57
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: HE1M
Also found by: 0xsomeone, AkshaySrivastav, Aymen0909, J4de, Koolex, Mohandes, bin2chen, brgltd, cccz, hals, ladboy233, max10afternoon, peanuts, rvierdiiev, shealtielanz, tsvetanovv, zzzitron
273.5673 USDC - $273.57
The L1 erc20 tokens bridge has a claimFailedDeposit function that allows to withdraw the tokens in cases where the deposit transaction on L2 were to fail. Also a bridge might have a deposit limit, which can be added or modified at any time.
Adding a deposit limit for a token that doesn't have any, will cause the claimFailedDeposit
function to revert with an underflow for every deposit that has been processed before the update.
The deposit function of the L1ERC20Bridge contract internally calls the _verifyDepositLimit function, which verifies and update the deposit limit for the token being transferred by the user, if existent:
IAllowList.Deposit memory limitData = IAllowList(allowList).getTokenDepositLimitData(_l1Token); if (!limitData.depositLimitation) return; // no deposit limitation is placed for this token if (_claiming) { totalDepositedAmountPerUser[_l1Token][_depositor] -= _amount; } else { require(totalDepositedAmountPerUser[_l1Token][_depositor] + _amount <= limitData.depositCap, "d1"); totalDepositedAmountPerUser[_l1Token][_depositor] += _amount; }
As can be seen the totalDepositedAmountPerUser[_l1Token][_depositor]
variable, that keeps track of how many token each user has deposited, only gets updated if the deposit limit exist for the token.
The L1ERC20Bridge
contract also has a claimFailedDeposit function that allows to withdraw tokens on L1 in case where the L2 transaction fails. This function will also internally call _verifyDepositLimit
and update the deposit limit, by decreasing the amount deposited by the user.
If during the deposit the token doesn't have deposit limit the totalDepositedAmountPerUser[_l1Token][_depositor]
variable for the user won't be updated; therefor if the owner adds a deposit limit afterwards the _verifyDepositLimit
call of the claimFailedDeposit
function will revert with an underflow, since it will try to subtract the amount being withdraw from the default value of a uint256 which is 0. Preventing the user from getting the tokens back.
-The owner can update deposit limits by calling the setDepositLimit function of the AllowList contract, which is set in the constructor of the ERC20 bridge
Other
#0 - c4-pre-sort
2023-11-02T15:38:56Z
141345 marked the issue as duplicate of #425
#1 - c4-judge
2023-11-24T20:00:44Z
GalloDaSballo marked the issue as satisfactory