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

auto_withdraw messages revert when withdrawing on Ethereum but don't revert when sending on Starknet which may result in tokens permanently locked

Summary

A user can call deposit_tokens on the starknet side of the bridge, specifiying use_withdraw_auto=true and the deposit will not revert. However, on the ethereum side any attempt to consume the message will revert because of the WITHDRAW_AUTO flag. Since canceling messages only works for messages sent from L1, there will be no way to release the tokens deposited on Starknet and they will be lost permanently.

Vulnerability Details

The WITHDRAW_AUTO option has been disabled on the Ethereum side of the bridge in the following code from Starklane::withdrawTokens:

if (Protocol.canUseWithdrawAuto(header)) {
// 2024-03-19: disabled autoWithdraw after audit report
// _consumeMessageAutoWithdraw(_starklaneL2Address, request);
revert NotSupportedYetError();
}

However, on the starknet side of the bridge, the option can still be specified when depositing tokens, and the flag is set in the bridging message without reverting:

fn deposit_tokens(
ref self: ContractState,
salt: felt252,
collection_l2: ContractAddress,
owner_l1: EthAddress,
token_ids: Span<u256>,
/*Note*/use_withdraw_auto: bool,
use_deposit_burn_auto: bool,
)
.
.
let req = Request {
header: compute_request_header_v1(ctype, use_deposit_burn_auto, /*Note*/use_withdraw_auto),
.
.
fn compute_request_header_v1(
ctype: CollectionType,
use_deposit_burn_auto: bool,
/*Note*/use_withdraw_auto: bool,
)
.
. /*Note*/
if (use_withdraw_auto) {
header = header | WITHDRAW_AUTO;
}

note that other than the comment on the Ethereum bridge code there is no mentioning that this option is disabled neither in the starknet bridge code nor in any dev documentation. Therefore users who access the starknet side of the bridge directly (either projects integrating the bridge or power users who access the bridge through code) can reasonably assume this options is available.

vulnerability scenario

  1. A user calls deposit_tokens on the starknet side and specifies use_withdraw_auto = true.

  2. The deposit succeeds and the user's NFT tokens are locked in the Starknet-side bridge.

  3. Once the message becomes available on the Ethereum Starknet Core contract, the user tries to consume the message by calling WithdrawTokens.

  4. However any attempt to call WithdrawTokens will revert, because of the code above that is meant to disable the use of WITHDRAW_AUTO.

  5. The user has no way to release the tokens from the starknet contract, since CancelRequest is only available for messages from L1 to L2.

root cause

Reverting on Auto Withdraw messages only on the Ethereum side of the bridge.

Impact

Permanent loss/lock of NFT tokens

Tools Used

Manual Review, Foundry, SNFoundry

Recommended Mitigation

Disable use_withdraw_auto on the Starknet side of the bridge by reverting deposit_tokens if called with use_withdraw_auto=true.

Updates

Lead Judging Commences

n0kto Lead Judge 10 months 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.