Starknet Auction

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

Reentrancy Vulnerability in withdraw Function

Summary

The withdraw function allows users (including the NFT owner and unsuccessful bidders) to withdraw their bids after the auction ends. However, the contract transfers funds to the caller before updating the internal state, making the contract vulnerable to a reentrancy attack.

Vulnerability Details

In the withdraw function:

if amount > 0 {
let sender = get_contract_address();
erc20_dispatcher.transfer_from(sender, caller, amount.into());
}
self.emit(Withdraw {amount: amount, caller: caller});

The contract transfers tokens (erc20_dispatcher.transfer_from) before removing or resetting the user’s bid amount in storage (self.bid_values). This allows a malicious contract to reenter the function and call withdraw multiple times, potentially draining the contract.

Impact

An attacker could drain the contract of all funds by calling withdraw repeatedly, exploiting the fact that the internal state is not updated before the transfer occurs.

Tools Used

Manual code review

Recommendations

  • Always update the internal state before making any external calls (e.g., token transfers) to prevent reentrancy attacks.

if amount > 0 {
self.bid_values.entry(caller).write(0); // Update state first
let sender = get_contract_address();
erc20_dispatcher.transfer_from(sender, caller, amount.into());
}
Updates

Lead Judging Commences

bube Lead Judge 9 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.