Summary
The contract does not currently prevent the NFT owner from placing a bid. This allows the NFT owner to potentially manipulate the auction by placing bids that could deter other bidders or artificially inflate the bid amount.
fn bid(ref self: ContractState, amount: u64) {
let time = get_block_timestamp();
let erc20_dispatcher = IERC20Dispatcher { contract_address: self.erc20_token.read() };
let sender = get_caller_address();
let receiver = get_contract_address();
let current_bid = self.highest_bid.read();
assert(self.started.read(), 'Auction is not started');
assert(time < self.bidding_end.read(), 'Auction ended');
assert(amount > current_bid, 'The bid is not sufficient');
self.bid_values.entry(sender).write(amount);
self.emit(NewHighestBid {amount: self.highest_bid.read(), sender: sender});
self.highest_bidder.write(sender);
self.highest_bid.write(amount);
erc20_dispatcher.transfer(receiver, amount.into());
}
Vulnerability Details
The current auction contract allows any user, including the NFT owner, to place bids without validation of their role. This lack of checks means that the NFT owner can interfere with the bidding process by participating in the auction, which is a conflict of interest.
Impact
If the NFT owner can place bids, they may exploit this ability to influence the auction outcome in their favor. They could place a high bid to discourage other participants or withdraw bids to manipulate the bidding dynamics. This leads to a lack of fairness and transparency in the bidding process.
Tools Used
Manual Review
Recommendations
Add the following check so that NFT owner cannot bid in the auction
assert(sender != self.nft_owner.read(), 'NFT owner cannot place a bid');
This is the modified bid function now
fn bid(ref self: ContractState, amount: u64) {
let time = get_block_timestamp();
let erc20_dispatcher = IERC20Dispatcher { contract_address: self.erc20_token.read() };
let sender = get_caller_address();
let receiver = get_contract_address();
let current_bid = self.highest_bid.read();
assert(self.started.read(), 'Auction is not started');
assert(time < self.bidding_end.read(), 'Auction ended');
assert(amount > current_bid, 'The bid is not sufficient');
assert(sender != self.nft_owner.read(), 'NFT owner cannot place a bid');
self.bid_values.entry(sender).write(amount);
self.emit(NewHighestBid {amount: self.highest_bid.read(), sender: sender});
self.highest_bidder.write(sender);
self.highest_bid.write(amount);
erc20_dispatcher.transfer(receiver, amount.into());
}