Since neither depositTokens or withdrawTokens are protected from re-entrancy, it is possible for an attacker to manipulate the protocol into the belief that a bridged token has not been escrowed. This can be exploited to create tokens which cannot be unbridged.
In this scenario, let's an attacker with a collectionL1 token that originates on Ethereum L1 (i.e. it is an Ethereum-native ERC-721 currently in circulation and not an IERC721Bridgeable).
First, the attacker calls depositTokens and bridges the token onto Starknet, and then withdraws  proxy token from the Starknet bridge.
Following this, the attacker then invokes escrow_deposit_tokens to initialize the process of unbridging the token back on the L1. Importantly, the attacker specifies their own malicious contract address as the req.ownerL1 receiver.
On Ethereum, the attacker calls withdrawTokens, which underlyingly  usessafeTransferFrom to transfer tokens, consequently invoking the onERC721Received callback on the attacker's malicious destination contract.
Since the L1 Bridge contract does not protect from re-entrancy, it is possible for the malicious contract to make a re-entrant invocation of depositTokens to re-deposit the token whilst the withdrawal from the escrow is still ongoing. Crucially, because the  _withdrawFromEscrow flow does not adhere to the Checks, Effects, Interactions pattern, we can see that after the attacker's deposit operation concludes, the Escrow contract makes the invalid assertion that _escrow[collection][id] = address(0x0), even though this token has indeed been escrowed.
After this, the token is bridged back to Starknet.
At this point in the attack, the attacker has successfully bridged an Ethereum-native token to Starknet, but the Bridge on Ethereum believes that the native token it holds has not been escrowed:
It is now impossible for the token to be unbridged back on Ethereum Mainnet, since invocations to withdrawTokens will correctly identify the correct mainnet address of the bridged token via _verifyRequestAddresses, but the bridged token will fail to return true for isEscrowed:
Consequently,  the Bridge contract will attempt to mintFromBridge, resulting in revert:
This makes it impossible to remove the token from the bridge.
It is possible for malicious users to prevent tokens from being ever bridged back from Ethereum Mainnet.
It is also plausable that  the machinations of complex dependent protocols may inadvertently lock up tokens on the Bridge if deposits were to be invoked re-entrantly, for example, based upon the dictation of an order book at a cross-chain hub.
Manual Review
Follow the CEI pattern:
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.