Tokens withdrawn from the bridge are not cleared from the escrow map in Bridge::withdraw_auto_from_l1.
An escrow map is defined as a map between collection's token_id and its depositor:
Bridge::escrow_deposit_tokens(...) is called to deposit tokens into the escrow, which updates the current owner of the token_id in the escrow map:
Bridge::withdraw_auto_from_l1(...), decorated with [L1_handler]which are special functions that can only be executed by a L1HandlerTransaction, processes message from L1 to withdraw tokens. It read the escrow map to check if a token_id is in escrow and if so, it transfers the token from the contract to its owner, otherwise it mints the token for that owner:
The problem is that the function never clear the escrow map after withdrawal, which means that even after a token has been withdrawn, the escrow map will still show the token_id as being in escrow. Take the following scenario:
Alice initially bridges token_x from L1 to L2. Since is_escrowed is initially false, token_x is minted from the bridge to Alice.
Alice bridges token_x back to L1 by calling Bridge::deposit_tokens(...), which transfers token_x from Alice to escrow. is_escrowed is now true on L2. Alice doesn't own the token now on L2.
Alice bridges the token back to L2 and since is_escrowed is true on L2, this piece of code will be triggered:
As we see, token_id is transferred from the escrow to Alice but is_escrowed remains true. Aside from this state inconsistency, this problem is worse if token_id was burned from the escrow (in use_deposit_burn_auto mode) because the function will try to transfer the non-existing token from the escrow instead of minting it which will always revert because well, token_id does not exist, permanently removing that token_id from circulation.
State inconsistency: is_escrowed is true when the token is not in the escrow.
Permanent removing oftoken_id from circulation in use_deposit_burn_auto mode.
Manual review.
Impact: Incorrect state without any other impact, which deserves a Low according to CodeHawks documentation.
Impact: Incorrect state without any other impact, which deserves a Low according to CodeHawks documentation.
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.