To call L1BossBridge::depositTokensToL2, a depositor needs to first approve the bridge to be able to transfer tokens from their address to the vault. The depositor would then call L1BossBridge::depositTokensToL2. When an approval has been made but deposit has not been called, an attacker can call L1BossBridge::depositTokensToL2 on behalf of the depositor and force them to deposit which can be withdrawn by their own L2 address.
In L1BossBridge::depositTokensToL2 on lines 70-78, the from address to deposit the tokens is specified as a parameter and L1Token::safeTransferFrom is called using this address:
This means that, if an approval has been made by a user, but deposit has not yet been called, an attacker can call deposit on behalf of the user and send the funds to their own L2 address by specifying l2address to be their own address.
An attacker can force users to deposit their tokens to the bridge and withdraw from the L2 using their own, attacking address.
Since users' funds are at risk, this is a high-impact, highly likely finding, which makes it high severity.
The following test simulates a user calling approve(), which is a floating approval, and an attacker calling depositTokensToL2() with an attacking address as the l2Recipient. The test passes demonstrating that the user's balance has decreased and the attacker has successfully deposited their approved tokens, to be withdrawn by the attacking address on the L2.
Remove the from parameter in L1BossBridge::depositTokensToL2:
This will ensure that the address calling L1BossBridge::depositTokensToL2 will now be the address that deposits the tokens.
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.