Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The ETH that user participates in the auction may be locked forever in some special scenarios #1603

Closed
c4-submissions opened this issue Nov 13, 2023 · 5 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-175 edited-by-warden satisfactory satisfies C4 submission criteria; eligible for awards

Comments

@c4-submissions
Copy link
Contributor

c4-submissions commented Nov 13, 2023

Lines of code

https://github.com/code-423n4/2023-10-nextgen/blob/8b518196629faa37eae39736837b24926fd3c07c/hardhat/smart-contracts/AuctionDemo.sol#L57-L61

Vulnerability details

Impact

The auctionDemo contract's participateToAuction function does not provide good condition verification.

When the auction ends, users can still participate. If a user calls the participateToAuction function at the auction's end timestamp, the ETH he provided for the bid may be permanently locked in the contract because the NFT may have already been claimed by the winner.

Proof of Concept

Let's assume that the timestamp of the end of the auction is exactly equal to the timestamp of a block.

Alice and Bob both want to win the NFT, and they broadcast their transactions at the same time within the last 12 seconds:

  1. Assume that Alice has bid 1 ETH and is currently the winner of the entire auction. She broadcasts a transaction calling the claimAuction function to successfully claim the NFT.
function claimAuction(uint256 _tokenid) public WinnerOrAdminRequired(_tokenid,this.claimAuction.selector){
    require(block.timestamp >= minter.getAuctionEndTime(_tokenid) && auctionClaim[_tokenid] == false && minter.getAuctionStatus(_tokenid) == true);
    auctionClaim[_tokenid] = true;
    uint256 highestBid = returnHighestBid(_tokenid);
    address ownerOfToken = IERC721(gencore).ownerOf(_tokenid);
    address highestBidder = returnHighestBidder(_tokenid);
    for (uint256 i=0; i< auctionInfoData[_tokenid].length; i ++) {
        if (auctionInfoData[_tokenid][i].bidder == highestBidder && auctionInfoData[_tokenid][i].bid == highestBid && auctionInfoData[_tokenid][i].status == true) {
            IERC721(gencore).safeTransferFrom(ownerOfToken, highestBidder, _tokenid);
            (bool success, ) = payable(owner()).call{value: highestBid}("");
            emit ClaimAuction(owner(), _tokenid, success, highestBid);
        } else if (auctionInfoData[_tokenid][i].status == true) {
            (bool success, ) = payable(auctionInfoData[_tokenid][i].bidder).call{value: auctionInfoData[_tokenid][i].bid}("");
            emit Refund(auctionInfoData[_tokenid][i].bidder, _tokenid, success, highestBid);
        } else {}
    }
}
  1. Bob's transaction follows closely, and he broadcasts a transaction offering 2 ETH to call the participateToAuction function to participate in the bidding.
function participateToAuction(uint256 _tokenid) public payable {
    require(msg.value > returnHighestBid(_tokenid) && block.timestamp <= minter.getAuctionEndTime(_tokenid) && minter.getAuctionStatus(_tokenid) == true);
    auctionInfoStru memory newBid = auctionInfoStru(msg.sender, msg.value, true);
    auctionInfoData[_tokenid].push(newBid);
}
  1. The above transactions are completed simultaneously in the last block. At this point, Bob's 2 ETH will be locked in the contract forever!

  2. Because the NFT has been taken by Alice, so Bob's call to the claimAuction function will not succeed. And the timestamp of the next block will be greater than the auction end timestamp, so Bob cannot call the cancelBid function to take his ETH back .

Tools Used

Foundry And VsCode

Recommended Mitigation Steps

optimize the participateToAuction function

function participateToAuction(uint256 _tokenid) public payable {
    require(msg.value > returnHighestBid(_tokenid) && block.timestamp <= minter.getAuctionEndTime(_tokenid) && minter.getAuctionStatus(_tokenid) == true);
+   require(auctionClaim[_tokenid] == true, " not allow to participate anymore ");    
    auctionInfoStru memory newBid = auctionInfoStru(msg.sender, msg.value, true);
    auctionInfoData[_tokenid].push(newBid);
}

Assessed type

Invalid Validation

@c4-submissions c4-submissions added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Nov 13, 2023
c4-submissions added a commit that referenced this issue Nov 13, 2023
@code4rena-admin code4rena-admin changed the title The ETH that the user participates in the auction may be locked forever in some special scenarios The ETH that user participates in the auction may be locked forever in some special scenarios Nov 13, 2023
@c4-pre-sort
Copy link

141345 marked the issue as duplicate of #962

@c4-judge
Copy link

c4-judge commented Dec 2, 2023

alex-ppg marked the issue as not a duplicate

@c4-judge
Copy link

c4-judge commented Dec 2, 2023

alex-ppg marked the issue as duplicate of #1926

@c4-judge
Copy link

c4-judge commented Dec 8, 2023

alex-ppg marked the issue as satisfactory

@c4-judge c4-judge added satisfactory satisfies C4 submission criteria; eligible for awards and removed 3 (High Risk) Assets can be stolen/lost/compromised directly labels Dec 8, 2023
@c4-judge
Copy link

c4-judge commented Dec 9, 2023

alex-ppg changed the severity to 2 (Med Risk)

@c4-judge c4-judge added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value downgraded by judge Judge downgraded the risk level of this issue labels Dec 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-175 edited-by-warden satisfactory satisfies C4 submission criteria; eligible for awards
Projects
None yet
Development

No branches or pull requests

4 participants