NextGen - CSL's results

Advanced smart contracts for launching generative art projects on Ethereum.

General Information

Platform: Code4rena

Start Date: 30/10/2023

Pot Size: $49,250 USDC

Total HM: 14

Participants: 243

Period: 14 days

Judge: 0xsomeone

Id: 302

League: ETH

NextGen

Findings Distribution

Researcher Performance

Rank: 148/243

Findings: 1

Award: $2.77

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Lines of code

https://github.com/code-423n4/2023-10-nextgen/blob/main/hardhat/smart-contracts/AuctionDemo.sol#L116

Vulnerability details

high

Lines of code

https://github.com/code-423n4/2023-10-nextgen/blob/main/hardhat/smart-contracts/AuctionDemo.sol#L116

Vulnerability details

The function claimAuction() is designed to let the winner in acquiring the NFT, making the corresponding payment, and also refunding the unsuccessful bidders. However, a potential issue arises if the unsuccessful bidder happens to be a malicious contract, as this could lead to a Denial of Service (DoS) scenario.

    function claimAuction(uint256 _tokenid) public WinnerOrAdminRequired(_tokenid,this.claimAuction.selector){
		......
        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 {}
        }
    }

Proof of Concept

  • At the initiation of the auction, a hacker deploys a malicious contract featuring a fallback() function embedded with an infinite loop (while(true)). By initiating a 1 Wei payment, the hacker triggers the participateToAuction() function, participating in the bidding.
contract Hack{
	.....
	fallback() external payable{
		while(true){
		
		}
	}
}
  • As the auction concludes and claimAuction() is invoked for settlement, the call() operation invokes the fallback() of the malicious contract, consuming 63/64 of the gas.
  • Given that this malicious contract precedes auctionInfoData[_tokenid] [i], subsequent users are left with only 1/64 of the available gas. If the array size is slightly larger, there is a substantial likelihood that it cannot be fully traversed (only a minimal portion is traversed). Consequently, funds from remaining participants persist indefinitely within the contract, and successful bidders are unable to claim their auctioned items.
  • Don’t send money, let users withdraw money themselves, this is the best practice
  • The account placing restrictions on bidding must be an Externally Owned Account (EOA).
  • Limit the gas used by call() calls

Assessed type

Payable

#0 - c4-pre-sort

2023-11-20T02:00:27Z

141345 marked the issue as duplicate of #163

#1 - c4-judge

2023-12-01T23:54:37Z

alex-ppg marked the issue as not a duplicate

#2 - c4-judge

2023-12-01T23:54:49Z

alex-ppg marked the issue as duplicate of #1782

#3 - c4-judge

2023-12-08T20:50:27Z

alex-ppg marked the issue as satisfactory

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Β© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter