The withdrawTokens
function in the bridge.sol
contract is vulnerable to re-entrancy attacks. This vulnerability arises from the order of operations in the _withdrawFromEscrow
function, where the token transfer occurs before the escrow
state is updated.
When a user calls withdrawTokens on bridge
contract to withdraw tokens received from L2, it verifies for each token ID in the request payload whether it is escrowed or not by calling the _withdrawFromEscrow
function:
Inside _withdrawFromEscrow, if the token is found in the escrow (checked by _isEscrowed(collection, id)
), the token is transferred using safeTransferFrom
:
The critical issue is that the escrow
state is updated after the token transfer.
The safeTransferFrom
calls invoke the onERC721Received
function in the to
address (i.e., the recipient contract). If the recipient contract is malicious, it could recursively call withdrawTokens
before the escrow state (_escrow[collection][id] = address(0x0);)
is updated.
Bridge contract on L1 can be drained of its escrowed tokens.
Manual Review
Update the _escrow
state before calling safeTransferFrom
:
Impact: - NFT already bridged won’t be bridgeable anymore without being stuck. Likelyhood: Low. - Attackers will corrupt their own tokens, deploying a risky contract interacting with an upgradable proxy. They have to buy and sell them without real benefits, except being mean. Some really specific and rare scenario can also trigger that bug.
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.