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
Rank: 95/243
Findings: 2
Award: $25.24
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 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
0 USDC - $0.00
https://github.com/code-423n4/2023-10-nextgen/blob/main/smart-contracts/AuctionDemo.sol#L58 https://github.com/code-423n4/2023-10-nextgen/blob/main/smart-contracts/AuctionDemo.sol#L125
The smart contract governing the auction system is susceptible to bid manipulation, allowing a user to exploit the bidding process and potentially gain an unfair advantage. The issue arises when a participant makes a small initial bid, subsequently places a significantly higher bid so potentially no other user can bid higher, and then cancels the last bid just before the auction concludes so he buy the item with the much lower bid amount. This manipulation can result in the auction system recognizing the earlier, smaller bid as the highest, potentially allowing the user to cancel a larger bid and unfairly influence the auction outcome. The impact includes a compromised auction integrity, potential financial losses for legitimate participants, and an overall degradation of trust in the auction platform.
The vulnerability allows a user to manipulate the bidding process, placing a small initial bid and then canceling a subsequent, larger bid just before the auction concludes. Financial losses may occur for participants who bid competitively and expect a fair auction process. the seller would be prevented from gaining more valid value for his art and may end up selling it for very small money.
a user would make a bid from the start which d be a small amount then directly make a very high bid just after it so no other user bid higher
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); }
just before the end of auction the user cancel his last bid(the very high bid) so the next high bid will be his much lower bid just before the last one
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); }
like this the user will buy the item with a very low price without having users compete against him
manual review
To mitigate the bid manipulation vulnerability, you can implement a relative bidding mechanism. This mechanism ensures that bid updates must be proportionally higher than the current highest bid, preventing users from manipulating the system by canceling and placing significantly lower bids.
Access Control
#0 - c4-pre-sort
2023-11-19T10:42:41Z
141345 marked the issue as duplicate of #962
#1 - c4-judge
2023-12-02T15:12:42Z
alex-ppg marked the issue as not a duplicate
#2 - c4-judge
2023-12-02T15:15:45Z
alex-ppg marked the issue as duplicate of #1784
#3 - c4-judge
2023-12-07T11:50:15Z
alex-ppg marked the issue as duplicate of #1323
#4 - c4-judge
2023-12-08T17:23:21Z
alex-ppg marked the issue as partial-25
#5 - c4-judge
2023-12-08T17:27:59Z
alex-ppg marked the issue as satisfactory
#6 - c4-judge
2023-12-08T18:13:05Z
alex-ppg marked the issue as partial-25
🌟 Selected for report: bird-flu
Also found by: 00decree, 0xAadi, AS, Audinarey, DeFiHackLabs, Eigenvectors, Fitro, Hama, Kaysoft, Krace, REKCAH, SovaSlava, The_Kakers, Viktor_Cortess, cartlex_, degensec, devival, evmboi32, funkornaut, jacopod, openwide, peanuts, rotcivegaf, smiling_heretic, xAriextz, xiao
25.2356 USDC - $25.24
https://github.com/code-423n4/2023-10-nextgen/blob/main/smart-contracts/AuctionDemo.sol#L113
The smart contract in question contains a critical issue related to the transfer of Ether during the auction claiming process. When a user claims their auction winnings, Ether is meant to be transferred to the owner of the token being auctioned. However, the current implementation mistakenly transfers Ether to the contract's owner instead. This error can have significant consequences as it results in the incorrect distribution of funds, potentially causing financial losses for the users involved in the auction. Additionally, it could lead to unexpected behavior and disputes regarding the ownership of tokens and funds.
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}(""); // should be ownerOfToken emit ClaimAuction(owner(), _tokenid, success, highestBid); }.. }
manual review
To address this issue, it is crucial to modify the Ether transfer mechanism in the contract's claim auction function. Specifically, replace owner() with the variable ownerOfToken in the payable call:
(bool success, ) = payable(ownerOfToken).call{value: highestBid}("");
Context
#0 - c4-pre-sort
2023-11-19T10:43:19Z
141345 marked the issue as duplicate of #245
#1 - c4-judge
2023-12-08T22:27:56Z
alex-ppg marked the issue as satisfactory