NFTBridge
60,000 USDC
View results
Submission Details
Severity: medium
Valid

L1 withdraw permanently stuck when `use_withdraw_auto == true`

Summary

Starknet L2 → L1 messaging still doesn’t have a way to be canceled in the same way that L1 → L2 can be. This precondition combined with the leftover code from the ERC1155 integration will make the L2 → L1 bridged tokens to be permanently stuck.

Vulnerability Details

When tokens are bridged from Starknet there is a single parameter that is left from the temporarily unused ERC1155 functionality: use_withdraw_auto

bridge.cairo

fn deposit_tokens(
ref self: ContractState,
salt: felt252,
collection_l2: ContractAddress,
owner_l1: EthAddress,
token_ids: Span<u256>,
use_withdraw_auto: bool, <---------------
use_deposit_burn_auto: bool,
) {

In normal situations and what the intentions of the Ark team are, it should not matter whether users pass true or false to this argument. But in reality, passing use_withdraw_auto will lead to a complete loss of the token because Bridge::withdrawTokens will be reverting when the header is being decoded and verified:

Bridge.sol

function withdrawTokens(
uint256[] calldata request
)
external
payable
returns (address)
{
if (!_enabled) {
revert BridgeNotEnabledError();
}
// Header is always the first uint256 of the serialized request.
uint256 header = request[0];
// Any error or permission fail in the message consumption will cause a revert.
// After message is consumed, it is considered legit and tokens can be withdrawn.
if (Protocol.canUseWithdrawAuto(header)) {
// 2024-03-19: disabled autoWithdraw after audit report
// _consumeMessageAutoWithdraw(_starklaneL2Address, request);
revert NotSupportedYetError(); <-------------------------
}

As we can see this change was introduced after the previous audit and due to missing proper mitigation, this will revert with NotSupportedYetError and as we saw above, since there is no mechanism to cancel failing messages from L2 to L1 tokens will be forever locked.

The root cause of the issue is the missing input validation in deposit_tokens for the current iteration of the protocol.

Impact

  • Loss of funds, due to unvalidated input parameter.

Tools Used

Manual Review

Recommendations

Prevent users from passing use_withdraw_auto == true.

Updates

Lead Judging Commences

n0kto Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-auto_withdrawn-L2-NFT-stuck

Impact: High, token will be stuck in L2 bridge. Likelyhood: Very low, option is available in L2 but has been disabled since March on L1, would be almost a user error.

Support

FAQs

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