withdrawTokens function in Bridge.sol does not check whether token being withdrawn is still whitelisted. This is because whitelisting of tokens on L1 and L2 sides is done independently and hence 1 side of the bridge might temporarily be whitelisted while the other side isnt.
withdrawTokens does not check whether an existing collection_l1 is still whitelisted before processing the transaction. If it is a new collection on L1 side, then it is deployed and whitelisted
https://github.com/Cyfrin/2024-07-ark-project/blob/273b7b94986d3914d5ee737c99a59ec8728b1517/apps/blockchain/ethereum/src/Bridge.sol#L183
But if it already exists, then the call to safeTransferFrom
is made from _withdrawFromEscrow
function without any check for whitelist.
But this call might go to a compromised contract.
In the test above the whitelisting was removed for the collection_l1
Running forge test test_depositWithdrawTokens_withMapping
shows the test passing and confirms the finding.
The impact could be severe and result in loss of NFT for receiver if the collection was removed from whitelist on L1 side due to the collection being compromised in any way.
Manual review
Changes to the whitelist should be made only from 1 side of the bridge through Starknet Messaging call, preferrably from L1 side since the call on L2 side would be synchronous without requiring additional actions from the admin. This will ensure there is only 1 source of truth for such data. Alternatively, the withdrawTokens function could check if collection_l1
is whitelisted and revert if it isnt whitelisted. But this would mean that the user's NFT gets stuck in escrow on L2 side and new code has to be developed to retrieve such stuck NFT through admin action.
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.