Starknet Auction

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

Multiple-Spend Vulnerability in Auction End Function

Summary

The end function fails to reset the highest_bidder's balance in the bid_values mapping to zero after transferring the NFT. This oversight allows the highest bidder to withdraw their funds even after receiving the auctioned NFT, potentially leading to a double-spend scenario.

Vulnerability Details

The vulnerability is located in the end function of the StarknetAuction contract. After the auction ends and the NFT is transferred to the highest bidder, the function does not update the bid_values mapping for the highest bidder. As a result, the highest bidder's balance remains unchanged in the contract's state.

Impact

This vulnerability can lead to a severe financial loss for the auction contract. The highest bidder can exploit this oversight by:

  1. Winning the auction and receiving the NFT.

  2. Calling the withdraw function to retrieve their bid amount.

This results in the highest bidder obtaining both the NFT and their original bid amount, effectively allowing them to acquire the NFT for free and depleting the contract of funds meant for the NFT owner.

Tools Used

Manual review

Recommendations

  1. In the end function, add a line to reset the highest bidder's balance in the bid_values mapping:

    fn end(ref self: ContractState) {
    // ...
    erc721_dispatcher.transfer_from(sender, self.highest_bidder.read(), self.nft_id.read().into());
    // Add this line
    self.bid_values.entry(self.highest_bidder.read()).write(0);
    }
  2. Consider adding a check in the withdraw function to ensure that the highest bidder cannot withdraw funds after the auction has ended:

    fn withdraw(ref self: ContractState) {
    // ...
    let caller = get_caller_address();
    assert(caller != self.highest_bidder.read() || !self.ended.read(), 'Highest bidder cannot withdraw after end');
Updates

Lead Judging Commences

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

The `highest_bidder` can withdraw the value of all bids

The `withdraw` function allows the participants to receive back the value of all their unsuccessful bids. The problem is that the winner of the auction will receive all bids including the `highest_bid` that should be paid to the NFT owner.

Support

FAQs

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