malicious user can steal his collateral back after he wins the auction
Summary
In current implementation, a bidder can cancel and withdraw his collateral if he is not the highest bidder. And if the user is the highest bidder, his collateral can't be withdrawn and will be transferred to privious owner when EnglishPeriodicAuctionFacet.closeAuction is called.
In EnglishPeriodicAuctionInternal._cancelBid, there is a check to make sure the bidder isn't the highest bidder. But in EnglishPeriodicAuctionInternal._cancelAllBids, the function lacks of such check, without the check, a malicious user can steal his collateral after he wins the auction.
416 function _cancelAllBids(uint256 tokenId, address bidder) internal {
417 EnglishPeriodicAuctionStorage.Layout
418 storage l = EnglishPeriodicAuctionStorage.layout();
419
420 uint256 currentAuctionRound = l.currentAuctionRound[tokenId];
421
422 for (uint256 i = 0; i <= currentAuctionRound; i++) {
423 Bid storage bid = l.bids[tokenId][i][bidder]; /// <<<--- function doesn't check if the bidder is the highest bidder here.
424
425 if (bid.collateralAmount > 0) {
426 // Make collateral available to withdraw
427 l.availableCollateral[bidder] += bid.collateralAmount;
428
429 // Reset collateral and bid
430 bid.collateralAmount = 0;
431 bid.bidAmount = 0;
432 }
433 }
434 }
attack step:
Alice(the malicious user) calls EnglishPeriodicAuctionFacet.placeBid with enough large amount of collateral to win the auction
When the auction ends, Alice calls EnglishPeriodicAuctionFacet.cancelAllBidsAndWithdrawCollateral immediately after the auction ends, before EnglishPeriodicAuctionFacet.closeAuction is called.
Impact
Without the check, malicious user can steal his collateral back after he wins the auction
jasonxiale
high
malicious user can steal his collateral back after he wins the auction
Summary
In current implementation, a bidder can cancel and withdraw his collateral if he is not the highest bidder. And if the user is the highest bidder, his collateral can't be withdrawn and will be transferred to privious owner when
EnglishPeriodicAuctionFacet.closeAuction
is called. InEnglishPeriodicAuctionInternal._cancelBid
, there is a check to make sure thebidder
isn't the highest bidder. But inEnglishPeriodicAuctionInternal._cancelAllBids
, the function lacks of such check, without the check, a malicious user can steal his collateral after he wins the auction.Vulnerability Detail
In EnglishPeriodicAuctionInternal._cancelBid, there is a check to make sure the bidder is not the highest bidder in the aution in EnglishPeriodicAuctionInternal.sol#L393-L396
But in EnglishPeriodicAuctionInternal._cancelAllBids, the function lacks of such check.
attack step:
EnglishPeriodicAuctionFacet.placeBid
with enough large amount of collateral to win the auctionEnglishPeriodicAuctionFacet.cancelAllBidsAndWithdrawCollateral
immediately after the auction ends, beforeEnglishPeriodicAuctionFacet.closeAuction
is called.Impact
Without the check, malicious user can steal his collateral back after he wins the auction
Code Snippet
https://github.com/sherlock-audit/2024-02-radicalxchange/blob/459dfbfa73f74ed3422e894f6ff5fe2bbed146dd/pco-art/contracts/auction/EnglishPeriodicAuctionInternal.sol#L416-L434
Tool used
Manual Review
Recommendation
Duplicate of #14