Submitted by The_Kakers, also found by btk (1, 2), TuringConsulting, immeas, yojeff, DeFiHackLabs, audityourcontracts, Toshii, DarkTower, CSL, codynhat, lsaudit, trachev, Vagner, Greed, 0xDetermination, gumgumzum, lanrebayode77, 0xJuda, ke1caM, Al-Qa-qa, Valix, NentoR, glcanvas, CaeraDenoir, MaNcHaSsS, NoamYakov, 0xAsen, mrudenko, innertia, SovaSlava, Talfao, r0ck3tz, 0xlemon, 00xSEV, 0xhunter, VAD37, Arabadzhiev, PENGUN, niki, nmirchev8, flacko, Soul22, ZdravkoHr, 0xpiken, funkornaut, Ruhum, 0xWaitress, Viktor_Cortess, openwide, oualidpro, rvierdiiev, and Haipls
claimAuction() implements a push-strategy instead of a pull-strategy for returning the bidders funds.
This gives the opportunity for an adversary to DOS the function, locking all funds from other participants.
This finding differs from the automated findings report M-01, and L-18, as it has a different root cause, cant be prevented with any of the mitigations from the bot, and also highlights the actual High impact of the issue.
All Ether from the auction can be lost as there is no alternate way of recovering it.
This also breaks one of the main invariants of the protocol:
An adversary can create bids for as little as 1 wei, as there is no minimum limitation: AuctionDemo.sol#L58. With that, it can participate in as many auctions as they want to grief all auctions.
All non-winning bidders that didnt cancel their bid before the auction ended will receive their bids back during claimAuction():
AuctionDemo.sol#L116
The contracts call the bidders with some value. If the receiver is a contract, it can execute arbitrary code. A malicious bidder can exploit this to make the claimAuction() always revert, and so no funds to other participants be paid back.
With the current implementation, a gas bomb can be implemented to perform the attack. L-18
from the automated findings report suggests the use of excessivelySafeCall() to prevent it, but it limits the functionality of legit contract receivers, and eventually preventing them from receiving the funds. In addition, the finding doesnt showcase the High severity of the issue and may be neglected.
M-01 from the automated findings report points out the lack of a check of the success of the calls. If the function reverts when the call was not successful, the adversary can make a callback on its contract receive() function to always revert to perform this same attack. In addition, this finding also doesnt showcase the High severity of the issue.
Ultimately the way to prevent this attack is to separate the transfer of each individual bidder to a separate function.
Create a separate function for each bidder to claim their funds back (such as the cancel bids functions are implemented).
ETH-Transfer
a2rocket (NextGen) acknowledged and commented via duplicate issue #1703:
0xsomeone (judge) commented:
