If you bridge native L2 collection to L1, you can't bridge it back because of a failed if statement in verify_collection_address
. This check will fail:
Let's consider the scenario of having a native L2 collection, not yet bridged. Now let's follow the flow of bridging a token and then bridging it back.
We call deposit_tokens()
on the L2 contract, collection_l2
is the address of the collection on the L2 and this returns address(0) since the l1 -> l2 mappings are not updated because we bridge for the first time:
Now, the message is processed and we call withdrawTokens()
on the L1 contract. This returns address(0) since the collection is yet to be deployed on the L1:
and we enter this if:
which proceeds to deploy the collection and correctly updates the _l1ToL2Addresses
and _l2ToL1Addresses
mappings:
Now let's try and bridge back the same token. We call depositTokens()
on L1 and these expressions return the stored addresses for the collection both for L1 and L2 since we updated them with the deployment of the collection on L1:
The request is processed and withdraw_auto_from_l1()
is called on the L2. Let's focus on this line:
and focus on the first lines of the function:
Here the values for l1_req
and l2_req
will be the corresponding addresses of the collection on L1 and L2 since that's what we passed to the request. However, self.l2_to_l1_addresses.read(l2_req)
and self.l1_to_l2_addresses.read(l1_req)
both will be address(0) since these mappings were never updated.
Now let's see the verify_collection_address()
function:
Since l2_req
is not zero we'll enter the else statement and this will fail:
because l2_bridge
represents the address of the L2 collection stored in the bridge contract which currently is 0, while the l2_req
represents the address we passed with the request, which is not 0.
When users bridge a native L2 collection from L2 -> L1 they won't be able to bridge back breaking the most critical functionality of the protocol
Manual review
I think it's safe to assume the l2_req
value is correct since it's the L1 bridge contract that passes it. So you can just return l2_req
in the else statement.
Likelyhood: High, any collections bridged, without bridge owner action, will be unable to bridge back. Impact: High, L2 -> L1 tokens will be stuck in the bridge. L1 -> L2 will need to ask for a cancellation.
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.