Deposit can be frontrun and stolen
In order to make a deposit into the bridge a user would first have to
approve the bridge to spend the user's tokens, and then make the deposit call.
An attacker could easily sandwich in a transaction after the approval but
before the deposit transaction and steal the users funds.
Either by picking up the transaction from the mempool or a mined block,
and then spending enough gas to slot in before the user's deposit transaction.
This is possible because the protocol function depositTokensToL2()
allows
setting the address from which tokens should be transferred. An attacker
could set someone else's address as from
and their own as the recipient
address on the L2 side. This would be the flow:
Victim approves bridge to spend X amount of tokens
Attacker calls depositTokensToL2()
specifying victim
address as from
and X as the amount, with their own
address as the L2 recipient.
Bridge will try to transfer tokens from the victim, which
will be successful since they have given approval.
Victim tries to deposit, but attacker has already spent the victim's tokens.
Even without frontrunning this mechanism is extremely dangerous since
an attacker can deposit and bridge someone elses tokens if they have given
for example infinite approval to the bridge, which is not uncommon.
Add this import:
and the following test case. It will succeed if the attacker is able to steal the funds.
The attack does succeed and the logs show the sequence of events:
Attacker can steal other users' deposits and also potentially all their tokens
(if the victim has given the protocol infinite or large allowance amount).
Manual review
Remove from
parameter from depositTokensToL2.
Use msg.sender
as the address to transfer tokens from.
Change signature from:
to:
Then use msg.sender
instead of from
inside the function.
This way, the bridge will only try to transfer tokens from the actual caller, and an attacker will have no way to spend the user's token balance.
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.