A bidder can cancel his bids after the execution of the auctionDemo.claimAuction
#1028
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-1323
partial-50
Incomplete articulation of vulnerability; eligible for partial credit only (50%)
Lines of code
https://github.com/code-423n4/2023-10-nextgen/blob/8b518196629faa37eae39736837b24926fd3c07c/smart-contracts/AuctionDemo.sol#L105
Vulnerability details
The
auctionDemo
contract allows to call thecancelBid
or thecancelAllBids
even after the execution of theclaimAuction
if both calls are executed in a block withblock.timestamp == minter.getAuctionEndTime(_tokenid)
. To illustrate it let's assume the following scenario:block.timestamp == minter.getAuctionEndTime(_tokenid)
:claimAuction
- the bidder can call this method since he is the winner andblock.timestamp >= minter.getAuctionEndTime(_tokenid)
cancelAllBids
- the bidder can call this method sinceblock.timestamp <= minter.getAuctionEndTime(_tokenid)
and theclaimAution
doesn't change the status of the bids.claimAution
cancelAllBids
since all of his bids can be canceledSo basically the bidder gets the NFT for free and additionally steals 1 ether (in this scenario; it is possible to steal everything with some preconditions) from the auction contract.
The attack above is simplified and therefore is not optimal. To increase the probability of success the bidder can deploy some proxy contract that can:
claimAuction
cancelAllBids
in thereceive
if all attack conditions are met:block.timestamp == minter.getAuctionEndTime(_tokenid)
In this case, the bidder can send only one transaction, and therefore the probability of success is higher.
Since the timestamp of the next block on Ethereum is quite predictable the probability of this attack is relatively high. If the attack doesn't succeed the bidder will still get the NFT and receive all non-winning bids back so the user doesn't risk losing anything.
It is also worth mentioning that an attacker is not obligated to be a winner to perform this attack. If a bidder is not a winner he can still use the aforementioned proxy contract that will help him to call the
cancelAllBids
if all conditions are met. But since a bidder can't control theclaimAuction
call time the probability of success is much lower in this case.Impact
A malicious user is able to steal ether from the
auctionDemo
contract with a significant probability.Proof of Concept
-
Tools Used
Manual Review
Recommended Mitigation Steps
Consider replacing the condition
block.timestamp >= minter.getAuctionEndTime(_tokenid)
with the strict oneblock.timestamp > minter.getAuctionEndTime(_tokenid)
in theauctionDemo.claimAuction
.Assessed type
Timing
The text was updated successfully, but these errors were encountered: