NextGen - max10afternoon'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: 205/243

Findings: 1

Award: $0.00

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: smiling_heretic

Also found by: 00decree, 00xSEV, 0x180db, 0x3b, 0x656c68616a, 0xAadi, 0xAleko, 0xAsen, 0xDetermination, 0xJuda, 0xMAKEOUTHILL, 0xMango, 0xMosh, 0xSwahili, 0x_6a70, 0xarno, 0xgrbr, 0xpiken, 0xsagetony, 3th, 8olidity, ABA, AerialRaider, Al-Qa-qa, Arabadzhiev, AvantGard, CaeraDenoir, ChrisTina, DanielArmstrong, DarkTower, DeFiHackLabs, Deft_TT, Delvir0, Draiakoo, Eigenvectors, Fulum, Greed, HChang26, Haipls, Hama, Inference, Jiamin, JohnnyTime, Jorgect, Juntao, Kaysoft, Kose, Kow, Krace, MaNcHaSsS, Madalad, MrPotatoMagic, Neon2835, NoamYakov, Norah, Oxsadeeq, PENGUN, REKCAH, Ruhum, Shubham, Silvermist, Soul22, SovaSlava, SpicyMeatball, Talfao, TermoHash, The_Kakers, Toshii, TuringConsulting, Udsen, VAD37, Vagner, Zac, Zach_166, ZdravkoHr, _eperezok, ak1, aldarion, alexfilippov314, alexxander, amaechieth, aslanbek, ast3ros, audityourcontracts, ayden, bdmcbri, bird-flu, blutorque, bronze_pickaxe, btk, c0pp3rscr3w3r, c3phas, cartlex_, cccz, ciphermarco, circlelooper, crunch, cryptothemex, cu5t0mpeo, darksnow, degensec, dethera, devival, dimulski, droptpackets, epistkr, evmboi32, fibonacci, gumgumzum, immeas, innertia, inzinko, jasonxiale, joesan, ke1caM, kimchi, lanrebayode77, lsaudit, mahyar, max10afternoon, merlin, mrudenko, nuthan2x, oakcobalt, openwide, orion, phoenixV110, pontifex, r0ck3tz, rotcivegaf, rvierdiiev, seeques, shenwilly, sl1, slvDev, t0x1c, tallo, tnquanghuy0512, tpiliposian, trachev, twcctop, vangrim, volodya, xAriextz, xeros, xuwinnie, y4y, yobiz, zhaojie

Awards

0 USDC - $0.00

Labels

bug
3 (High Risk)
partial-50
upgraded by judge
duplicate-1323

External Links

Lines of code

https://github.com/code-423n4/2023-10-nextgen/blob/71d055b623b0d027886f1799739b7f785b5bc7cd/smart-contracts/AuctionDemo.sol#L124

Vulnerability details

Impact

The auctionDemo contract enables users to cancel and withdraw any bid that they previously made, including the current highest bid. This means that a user can make a completely out of market bid completely discouraging other users from bidding again (eg: if an NFT from a collection is worth on average 10, they can bid for 50) and than cancel the bid at the last second, meaning that the auction will be virtually unavailable for the vast majority of the time.

This opens up for following scenarios:

  1. As the auction start a user can bid an out of market amount, wait till the last few seconds, than cancel the bid, preventing the majority of users from participating in the auction, likely getting the item sold for a discounted price, as the time left for bidding will be minimum.

  2. As the auction start a user can bid an out of market amount, wait till the last few seconds, than cancel the bid, than places a very low bid and (even 1 wei, if possible), if afterwards there is no time left (or extremely little) they might get the item for the specified extremely cheap price.

  3. An artist can artificially pump the price of their assets, without incurring in any risk, as they can always withdraw their highest bid (even if no one surpass them), to let the one immediately below win (frontrunnig withdraws if necessary).

  4. A validator knowing that they will mine blocks around the auction's end timestamp, can do the same trick of bidding extremely high, cutting away any competition, and then both delete the bid an create a new one, inside the block where the timestamp is equal to the end of the auction, getting the NFT at an artificially discounted price.

Proof of Concept

-1,2,3)

The auctionDemo contract, which enables NFT to be auctioned, has a cancelBid function, that lets users delete a bid and withdraw correspondent ETH:

function cancelBid(uint256 _tokenid, uint256 index) public { require(block.timestamp <= minter.getAuctionEndTime(_tokenid), "Auction ended"); require(auctionInfoData[_tokenid][index].bidder == msg.sender && auctionInfoData[_tokenid][index].status == true); auctionInfoData[_tokenid][index].status = false; (bool success, ) = payable(auctionInfoData[_tokenid][index].bidder).call{value: auctionInfoData[_tokenid][index].bid}(""); emit CancelBid(msg.sender, _tokenid, index, success, auctionInfoData[_tokenid][index].bid); }

As can be seen this function only checks that: -block.timestamp <= minter.getAuctionEndTime(_tokenid), the auction hasn't ended. -auctionInfoData[_tokenid][index].bidder == msg.sender, msg.sender is the one who placed the bid. -uctionInfoData[_tokenid][index].status == true and that the bid has not been already withdrawn.

This means that even the highest bid can be withdrawn, since there is no restriction against it, enabling the scenarios listet in Impact.

-4) As can be observed the checks against the auction's end performed by participateToAuction, cancelBid and claimAuction, the three functions necessary to place a new bid, delete an old one, and claim the price, are all performed using <= or >=:

function participateToAuction(uint256 _tokenid) public payable { require(msg.value > returnHighestBid(_tokenid) && block.timestamp <= minter.getAuctionEndTime(_tokenid) && minter.getAuctionStatus(_tokenid) == true);
function cancelBid(uint256 _tokenid, uint256 index) public { require(block.timestamp <= minter.getAuctionEndTime(_tokenid), "Auction ended");
function claimAuction(uint256 _tokenid) public WinnerOrAdminRequired(_tokenid,this.claimAuction.selector){ require(block.timestamp >= minter.getAuctionEndTime(_tokenid) && auctionClaim[_tokenid] == false && minter.getAuctionStatus(_tokenid) == true);

Meaning that they can all three be invoked in the same block for as long as block.timestamp == minter.getAuctionEndTime(_tokenid), enabling scenario 4, in the impact session

the cancelBid function could check that the bid that is being deleted, isn't the currently highest bid

Assessed type

Other

#0 - c4-pre-sort

2023-11-15T10:47:44Z

141345 marked the issue as duplicate of #962

#1 - c4-judge

2023-12-02T15:13:22Z

alex-ppg marked the issue as not a duplicate

#2 - c4-judge

2023-12-02T15:17:13Z

alex-ppg marked the issue as duplicate of #1784

#3 - c4-judge

2023-12-07T11:49:31Z

alex-ppg marked the issue as duplicate of #1323

#4 - c4-judge

2023-12-08T17:27:25Z

alex-ppg marked the issue as partial-50

#5 - c4-judge

2023-12-08T17:28:24Z

alex-ppg marked the issue as satisfactory

#6 - c4-judge

2023-12-08T18:24:25Z

alex-ppg marked the issue as partial-50

#7 - c4-judge

2023-12-09T00:20:29Z

alex-ppg changed the severity to 3 (High Risk)

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