When an NFT is liquidated it will be sent from the StabilityPool
to the NFTLiquidator
contract and a 3 days auction will start. Users can bid for the NFT via the placeBid
function or buy it directly via buyBackNFT
. The current design of the auction is to store the current highestBidder
address and if a new user bids more, the protocol attempts to repay the previous highestBidder
before overriding it.
The problem with this approach is that the whole auction system can be DoSed by placing a bid from a smart contract that implements a receive()
function that always reverts. When the placeBid
or buyBackNFT
functions attempt to repay the previous highestBidder
, the transaction will always revert and users are unable to place bids anymore. The auction system is permanently DOSed. The current design mimics almost perfectly the Ethernaut CTF level 09 King.
The crux of the attack relies on the assumption that the previous highestBidder
will always be successfully refunded. Since the NFTLiquidator
contract attempts to transfer tokens to the previous highestBidder
if this address is a smart contract that implements a receive()
function that always reverts, transferring tokens to that smart contract won't work, which will lead to reverting transactions. Check the code below
also here we have the same logic
Attack path
A malicious user creates a smart contract with a receive()
function that always reverts.
The attacker monitors liquidations and immediately bids a very small amount of tokens, say for example 0.000000001
tokens on each new auction.
Since the attacker's contract is now the highestBidder
subsequent user bids will always revert, DoSing the auctions permanently.
The whole auction system can be permanently DoS.
NFTs will remain locked in the NFTLiquidator
contract
Manual review
The refund logic for previous bidders needs an overhaul. I suggest storing the amounts that each previous highestBidder
is entitled to in a mapping of address -> unit, and after the auction ends, allow each user to claim their tokens back.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.