Skip to content

Second Highest Bidder Can illegally Secure the Auction if refund is rejected by him #42

Description

@aniket866

Problem

  • Person A bids ₹100 → they are the highest bidder.

  • Person B tries to bid ₹120.

  • Before accepting Person B’s bid, the system first sends back ₹100 to Person A.

  • If Person A is a smart contract that refuses to accept the refund, then:

  • The refund fails

  • The whole transaction fails

  • Person B’s bid is rejected

  • So no one else can bid anymore.

Summary

The bid() function in EnglishAuction.sol uses a push-based refund mechanism. If the previous highest bidder is a malicious smart contract (or token transfer fails), the refund reverts and blocks all future bids, effectively freezing the auction.

##Before:

uint256 refund = auction.highestBid;
address previousWinner = auction.winner;
auction.winner = msg.sender;
auction.highestBid = bidAmount;

if (refund != 0) {
    //  Direct refund causes DoS if receiver reverts
    sendERC20(auction.biddingToken, previousWinner, refund);
}

Fix :

Instead of sending refunds immediately:

  • Store refund amounts in a mapping
  • Let users withdraw refunds themselves

This prevents anyone from blocking the auction.

Fix Implementation

1. New State Variable

// user => token => amount
mapping(address => mapping(address => uint256)) public pendingReturns;

2. Updated bid() Logic

uint256 refund = auction.highestBid;
address previousWinner = auction.winner;
auction.winner = msg.sender;
auction.highestBid = bidAmount;

if (refund != 0) {
    // Store refund instead of sending
    pendingReturns[previousWinner][auction.biddingToken] += refund;
}

3. New withdrawRefund() Function

function withdrawRefund(address tokenAddress) external {
    uint256 amount = pendingReturns[msg.sender][tokenAddress];
    require(amount > 0, "No funds to withdraw");

    // Clear state before transfer (reentrancy-safe)
    pendingReturns[msg.sender][tokenAddress] = 0;

    sendERC20(tokenAddress, msg.sender, amount);
}

@kaneki003 What's your view on this, Please feel free to assign

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions