NFTBridge
60,000 USDC
View results
Submission Details
Severity: low
Invalid

Disabling L2 bridge leads to permanent stuck of inflight NFTs

Summary

When L2 bridge is disabled, already inflight NFTs (or NFTs that are deposited on L1 after L2 is disabled) would be impacted because they can not be withdrawn on L2. This message can not be retried either, so the NFT would be stuck on L1 permanently.

Vulnerability Details

Suppose an NFT is intended to be bridged from L1 to L2. Different scenarios can happen:

  • The NFT is deposited on L1, and while the message is inflight, the bridge on L2 becomes disabled by the admin. Since the withdrawal on L2 is auto, the function withdraw_auto_from_l1 would be called on L2, and it checks whether it is enabled or not. Since, it is disabled while the message was inflight, withdrawal transaction reverts.

ensure_is_enabled(@self);

https://github.com/Cyfrin/2024-07-ark-project/blob/main/apps/blockchain/starknet/src/bridge.cairo#L134

  • L2 bridge is disabled already. But, the L1 bridge is not disabled yet since L1 and L2 are asynchronous. So, depositing the NFT on L1 would be possible, but withdrawing on L2 would not be possible due to ensure_is_enabled(@self); in the function withdraw_auto_from_l1.

When any of these scenarios happen, starknet considers the message as accepted on L2 but the result is reverted. So, cancelling such messages from L1 would not be possible, because during processing the L1 to L2 messages, starknet sets messages[messageHash] = 0, i.e. the message is delivered on L2 (whether it is reverted or successful does not matter).

{
bytes32 messageHash = keccak256(
abi.encodePacked(programOutputSlice[offset:endOffset])
);
uint256 msgFeePlusOne = messages[messageHash];
require(msgFeePlusOne > 0, "INVALID_MESSAGE_TO_CONSUME");
totalMsgFees += msgFeePlusOne - 1;
messages[messageHash] = 0;
}

https://github.com/starkware-libs/cairo-lang/blob/v0.13.2a0/src/starkware/starknet/solidity/Output.sol#L151

Moreover, retrying a reverted message on starknet is not possible as the withdrawal is auto.

As a result, the NFT would be stuck on L1, while associated L2 collection is not released to the receiver.

Impact

  • Stuck/loss of NFT on L1.

Tools Used

Recommendations

It is recommended that in such scenarios during withdrawal on L2, the message be stored in a mapping, and later when the L2 bridge is enabled again, it can be withdrawn manually.

Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Informational / Gas

Please, do not suppose impacts, think about the real impact of the bug and check the CodeHawks documentation to confirm: https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity A PoC always helps to understand the real impact possible.

Appeal created

fyamf Submitter
10 months ago
n0kto Lead Judge
9 months ago
n0kto Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Informational / Gas

Please, do not suppose impacts, think about the real impact of the bug and check the CodeHawks documentation to confirm: https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity A PoC always helps to understand the real impact possible.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.