Starknet Auction

First Flight #26
Beginner FriendlyNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Lack of bid reset in the withdraw function allows unlimited fund withdrawal

Summary

A high-severity vulnerability has been identified in the StarkNet auction contract's withdraw function. The issue arises because participant bids are not reset after they withdraw their funds. This allows participants to invoke the withdraw function multiple times, potentially leading to unlimited fund withdrawals from the contract.

Vulnerability Details

In the current implementation of the withdraw function, participant bid values remain stored in the bid_values map after they have successfully withdrawn their funds. This means that after a participant calls withdraw, their bid remains unchanged in the storage, allowing them to call the function again and repeatedly withdraw the same amount of funds.

The function performs the following steps:

  1. Transfers funds back to the participant using erc20_dispatcher.transfer_from.

  2. Does not reset the participant’s bid value in bid_values after the withdrawal.

This results in a situation where a malicious participant can continually call the withdraw function and withdraw the same funds over and over again.

Impact

  • Unlimited Fund Withdrawal: Any participant who calls withdraw can continually withdraw their bid amount, draining the contract's funds indefinitely.

  • Financial Loss: This vulnerability could lead to the depletion of the entire contract balance, causing significant financial loss to the contract owner and other participants.

  • Critical Exploit: This issue directly affects the integrity of the auction process and could render the contract unusable due to the loss of funds.

Tools Used

  • Manual code review.

Recommendations

To resolve the issue and prevent both reentrancy attacks and multiple withdrawals, the participant's bid value in the bid_values map must be reset before the funds are transferred. However, to avoid sending 0 tokens, the correct sequence is:

  1. First, save the current bid amount.

  2. Then, reset the bid value in bid_values.

  3. Finally, transfer the funds.

    if amount > 0 {
    let withdrawal_amount = amount; // Save the current bid amount
    self.bid_values.entry(caller).write(0); // Reset the participant's bid to prevent reentrancy
    erc20_dispatcher.transfer_from(sender, caller, withdrawal_amount.into()); // Transfer the correct funds
    }
Updates

Lead Judging Commences

bube Lead Judge 8 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Reentrancy in `withdraw` function

The `withdraw` function doesn't reset the `bid_values` to 0 after the withdraw. That means the bidder can call multiple time the `withdraw` function and receive the whole balance of the protocol.

Support

FAQs

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