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

Empty `token_ids` deposit in Starknet leads to the creation of valid cross-chain messages without token transfers

Summary

The Starknet bridge.cairo contract allows deposits with zero token IDs, leading to the creation of valid cross-chain messages without actual token transfers. This vulnerability enables gas-wasting transactions and exposes the bridge to potential spam attacks, ultimately leading to critical inconsistencies in the bridge's state.

Vulnerability Details

The vulnerability is present in the deposit_tokens function of the Starknet bridge contract:

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,
) {
// ... (no check for empty token_ids)
escrow_deposit_tokens(ref self, collection_l2, from, token_ids);
// ... (message sending to L1)
}

The function lacks input validation to ensure that token_ids is not empty. This oversight allows the creation and processing of deposit transactions with no actual tokens, resulting in empty but valid cross-chain messages.

Impact

  • Allows creation and processing of meaningless transactions, consuming gas on both L1 and L2 without actual token transfers.

  • Generates deposit records and cross-chain messages that don't represent real token movements, potentially skewing bridge statistics and state.

  • The ability to send zero-ID deposits opens the bridge to potential spam attacks, which could congest the network and disrupt normal operations.

Tools Used

Manual review

Recommendations

Implement input validation in the deposit_tokens function:

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,
) {
assert(!token_ids.is_empty(), 'No tokens to deposit');
// ... rest of the function
}

OR Add a similar check in the escrow_deposit_tokens function (like you did in the Bridge.sol Ethereum side):

fn escrow_deposit_tokens(
ref self: ContractState,
contract_address: ContractAddress,
from: ContractAddress,
token_ids: Span<u256>,
) {
assert(!token_ids.is_empty(), 'No tokens to escrow');
// ... rest of the function
}
Updates

Lead Judging Commences

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

invalid-empty-tokenIds-starknet-side

No real impact. Attacker will have to pay the deployment of the new contract even with 0 token, and it won’t have any interest do to that since he won’t take the control of the contract.

Support

FAQs

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