NFT auction can be sabotaged in multiple ways, causing bidders' ETH to be permanently locked #278
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-364
unsatisfactory
does not satisfy C4 submission criteria; not eligible for awards
Lines of code
https://github.com/code-423n4/2023-10-nextgen/blob/main/smart-contracts/AuctionDemo.sol#L104-L120
Vulnerability details
Impact
Auction bidders lose all their bids permanently if 1) The owner of the auctioned NFT revokes the approval for the NFT or 2) The winner is a smart contract that rejects the ERC721 transfer.
Auction bidders temporarily lock their bids while
claimAuction
is not called by the winner or the admin.Description
AuctionDemo.sol
is an implementation of a highest-bidder auction for NFT's auctioned withMinterContract
's built-inmintAndAuction
mechanism. During the auction bidders can submit bids withparticipateToAuction
. After the auction ends the highest bidder can callclaimAuction
to get the NFT and refund all other participants.There are a few ways that auction participants can permanently lose their bids:
claimAuction
then the rest of the bidders will not receive their bids back. There is no other bid refunding mechanism after the auction is over.onERC721Received
hook then the bids will be permanently locked in the auction contract.claimAuction
, thus both the winner and the bidders lose their ETH, while the auctioneer keeps their NFT.Proof of Concept
The following Foundry test demonstrates the most severe vulnerability outlined above. The owner revokes the approval for the auctioned token, thus keeping their NFT. All bids are permanently lost inside the auction contract.
To run the PoC within the contest repo:
forge init
in the root directory of the contest repo.foundry.toml
configuration file with:test/AuctionSabotagePoC.t.sol
and paste the contents of the PoC:forge test --mc AuctionSabotagePoC
claimAuction
reverts with"ERC721: caller is not token owner or approved"
Tools Used
Manual Review, Foundry testing
Recommended Mitigation Steps
First, there is a design flaw in the auction contract. The logic should be changed such that the NFT must be transferred to the auction contract before the auction starts. When the auction contract custodies the auctioned NFT then the owner cannot sabotage by revoking approval.
Second, bidders must be given another way to get their bids back if they do not win. Implement a function
refundBid
which can be called after the auction ends. The function will refund a bidder if they are not the winner. In this way non-winners need not wait untilclaimAuction
is called before receiving their bids back.Assessed type
Rug-Pull
The text was updated successfully, but these errors were encountered: