Token owner's collateral will not be refunded if no one bids in the next auction round.
Summary
For each auction round, the highest bid at the end of the auction wins, and the bidder gains the ownership of the token for the next license period. By the next round, if the old owner loses the auction, his bitAmount will be refunded as availableCollateral. But if no one bids in the new auction round, the bitAmount will not be refunded, causing the old owner to lose his collateral.
Vulnerability Detail
As shown in _closeAuction, the oldBidder (the current owner of the token) will get his bitAmount back if he is not the new highest bidder (L500). However, if no one bids in the new auction round (L485), the token will goes to repossessor, but oldBidder does not get back his bitAmount in this case.
// EnglishPeriodicAuctionInternal.sol#_closeAuction()
465: function _closeAuction(uint256 tokenId) internal {
...
485:@> if (l.highestBids[tokenId][currentAuctionRound].bidder == address(0)) {
486: // No bids were placed, transfer to repossessor
487: Bid storage repossessorBid = l.bids[tokenId][currentAuctionRound][
488: l.repossessor
489: ];
490: repossessorBid.bidAmount = 0;
491: repossessorBid.feeAmount = 0;
492: repossessorBid.collateralAmount = 0;
493: repossessorBid.bidder = l.repossessor;
494:
495: l.highestBids[tokenId][currentAuctionRound] = repossessorBid;
496: } else if (
497: l.highestBids[tokenId][currentAuctionRound].bidder != oldBidder
498: ) {
499: // Transfer bid to previous bidder's collateral
500:@> l.availableCollateral[oldBidder] += l
501: .highestBids[tokenId][currentAuctionRound].bidAmount;
502: l.highestBids[tokenId][currentAuctionRound].collateralAmount = 0;
503: l
504: .bids[tokenId][currentAuctionRound][
505: l.highestBids[tokenId][currentAuctionRound].bidder
506: ].collateralAmount = 0;
507: } else {
508: l.highestBids[tokenId][currentAuctionRound].collateralAmount = 0;
509: l
510: .bids[tokenId][currentAuctionRound][oldBidder].collateralAmount = 0;
511: }
...
538: }
ydlee
high
Token owner's collateral will not be refunded if no one bids in the next auction round.
Summary
For each auction round, the highest bid at the end of the auction wins, and the bidder gains the ownership of the token for the next license period. By the next round, if the old owner loses the auction, his
bitAmount
will be refunded asavailableCollateral
. But if no one bids in the new auction round, thebitAmount
will not be refunded, causing the old owner to lose his collateral.Vulnerability Detail
As shown in
_closeAuction
, theoldBidder
(the current owner of the token) will get hisbitAmount
back if he is not the new highest bidder (L500). However, if no one bids in the new auction round (L485), the token will goes torepossessor
, butoldBidder
does not get back hisbitAmount
in this case.https://github.com/sherlock-audit/2024-02-radicalxchange/blob/main/pco-art/contracts/auction/EnglishPeriodicAuctionInternal.sol#L485-L511
The following test case shows the described senario (Insert the
it
function toEnglishPeriodicAuction.ts#placeBid
).Impact
If no one bids in the next auction round, the old owner of the token will lose his collaterals.
Code Snippet
https://github.com/sherlock-audit/2024-02-radicalxchange/blob/main/pco-art/contracts/auction/EnglishPeriodicAuctionInternal.sol#L485-L511
Tool used
Manual Review
Recommendation
Do not forge to refund
oldBidder
's collateral even if no one bids in new auction round.