π§ββοΈAuction
EnglishAuction
Inherits: Owned, RoyaltyEngineV1
Author: cosimo.demedici.eth (https://github.com/ninfa-labs/ninfa-contracts)
On-chain English Auction
State Variables
_dataFeed
Chainlink ETH/USDC price feed aggregator interface
Use Counters library for Counter datatype
AggregatorV3Interface private immutable _dataFeed;_DURATION
Duration of an auction once the first bid has been received. Set to 1 day.
uint256 private constant _DURATION = 1 days;_EXTENSION_DURATION
Window for auction extensions. Any bid placed in the final 15 minutes of an auction will reset the time remaining to 15 minutes.
_MIN_BID_RAISE
For example, _MIN_BID_RAISE = 10 is a 10% increment, 20 is 5%, 2 is 50%. I.e., 100 / _MIN_BID_RAISE.
The last highest bid is divided by this number to obtain the minimum bid increment.
_BPS_DENOMINATOR
Denominator for basis points calculation. 10,000 basis points = 100% shares sale price.
auctionCount
Counter for tracking the number of auctions
_feeRecipient
The address for receiving auction sales fees. Typically, this is a multisig address.
_feeBps
The Ninfa fee percentage on primary sales, expressed in basis points.
_auctions
This needs to be public so that it can be called by a frontend as the auction creation event only emits auction id.
Mapping from auction IDs to auction data. This is deleted when an auction is finalized or canceled.
Functions
constructor
Parameters
feeRecipient_
address
address (multisig) controlled by Ninfa that will receive any market fees.
feeBps_
uint256
onERC721Received
Creates an auction for the given NFT. The NFT is held in escrow until the auction is finalized or canceled.
Whenever an {IERC721} tokenId token is transferred to this contract via {IERC721-safeTransferFrom} by operator from from, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with IERC721.onERC721Received.selector.
Parameters
_operator
address
The address which called safeTransferFrom function
_from
address
The address which previously owned the token
_tokenId
uint256
The NFT identifier which is being transferred
_data
bytes
Additional data with no specified format
Returns
<none>
bytes4
bytes4 Returns bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))
firstBid
reservePrice is the initial reserve price for the auction. Reserve price may also be 0, clearly a mistake but not strictly required, only done in order to save gas by removing the need for a condition such as if (_price == 0) revert InvalidAmount(_price) commissionReceivers address of sale commissions receiver if msg.sender is also the _commissionReceiver, e.g. if msg.sender is a gallery, they must put their own address as the _commissionReceiver, and set the _seller parameter with the artist's/collector's address. if there is no commission receiver, it must be set to address(0) it is not required for _commissionReceiver and _seller addresses to be different (in order to save gas), although it would likely be a mistake, it cannot be exploited as the total amount paid out will never exceed the price set for the order. I.e. in the worst case the same address will receive both principal sale profit and commissions.
This function is to be used only for the first bid on any auction, in order to avoid code repetition and improve gas costs for all bids.
This function integrates third party credit card payment solution, as payment gateways will use their own contracts to call this function it is not possible to rely on msg.sender. It is also possible for the buyer to use this parameter simply in order to transfer the NFT to an address other than their own, this can be useful for external contract buying NFTs.
Parameters
_auctionId
uint256
_bidder
address
The address of the bidder
bid
Places a bid in an auction. The bid must be at least the amount defined by getMinBidAmount. If this is the first bid on the auction, the countdown will begin. If there is already an outstanding bid, the previous bidder will be refunded at this time. If the bid is placed in the final moments of the auction, the countdown may be extended.
Bids must be at least 5% higher than the previous bid. The _auctionId must exist, the auction must have begun, and must not have ended. The _bidder parameter is needed to integrate third-party credit card payment solutions.
Parameters
_auctionId
uint256
The id of the auction to bid on.
_bidder
address
The address of the bidder.
finalize
reverts if auction doesn't exist yet;, i.e. if _auction.end == 0
reverts if auction has been created but no one has called firstBid() yet. i.e. if _auction.end == 0
reverts if auction has ended, i.e. if block.timestamp > _auction.end
Reverts if raise is less than minimum raise pct required, i.e. bids Delta must be greater than or equal to the old bid value divided by _MIN_BID_RAISE.
Does not follow check-effects-interactions pattern in order to avoid storing previous bidder and amount in memory variables. No reentrancy exploit is possible in practice however; _auction.bidPrice and _auction.bidder are not used by any other function that may be reentered, namely onERC721Received() and firstBid().
finalize
Finalizes an auction. The NFT is held in escrow until the auction is finalized or canceled.
reverts if auction has started but not ended yet, i.e. block.timestamp < auction.end
reverts if auction does not exist or was already finalized/deleted, i.e. auction.end == 0
The reserve price may also be 0.
Parameters
_auctionIds
uint256[]
The ids of the auctions to finalize.
updateReservePrice
If an auction has been created but has not yet received bids, the reservePrice may be edited by the seller.
reverts if auction has started but not ended yet, i.e. block.timestamp < auction.end
reverts if auction does not exist or was already finalized/deleted, i.e. auction.end == 0
_newReservePrice may be equal to old price (_auctions[_auctionId].price); although this doesn't make much sense it isn't a security requirement, hence require(_auction.bidPrice != _price) it has been omitted in order to save the user some gas
_newReservePrice may also be 0, clearly a mistake but not a security requirement, hence require(_price > 0) has been omitted in order to save the user some gas
Parameters
_auctionId
uint256
The id of the auction to change.
_newReservePrice
uint256
The new reserve price for this auction, may be higher or lower than the previoius price.
updateCommissionBps
If an auction has been created but has not yet received bids, the commissionBps may be edited by the seller.
Parameters
_auctionId
uint256
The id of the auction to change.
_commissionBps
uint256[]
The new commission basis points for this auction.
_commissionReceivers
address[]
The new commission receivers for this auction.
cancelAuction
If an auction has been created but has not yet received bids, it may be canceled by the seller.
The NFT is transferred back to the owner unless there is still a buy price set.
Parameters
_auctionId
uint256
The id of the auction to cancel.
setFeeRecipient
Setter function only callable by contract admin used to change the address to which fees are paid.
Parameters
_newFeeRecipient
address
is the address owned by NINFA that will collect sales fees.
setFeeBps
Setter function only callable by contract admin used to change the fee percentage on primary sales.
Parameters
_newFeeBps
uint256
is the new fee percentage in basis points.
getAuction
Returns the minimum bid amount for an auction.
Parameters
_auctionId
uint256
The id of the auction to get the minimum bid amount for.
Returns
<none>
Auction
The minimum bid amount.
supportsInterface
See IERC165-supportsInterface. A wallet/broker/auction application MUST implement the wallet interface if it will accept safe transfers.
Events
AuctionCreated
Emitted when an auction is created. All auction data is stored in db by reading Auction struct after events are emitted, therefore information can be retrieved even after an AuctionFinalized event has been emitted and the corresponding auction struct deleted from storage.
AuctionCanceled
Emitted when an auction is canceled.
AuctionUpdated
Emitted when an auction is updated.
AuctionFinalized
Emitted when an auction is finalized.
Bid
Emitted when a bid is placed in an auction.
Structs
Auction
This struct stores the auction configuration for a specific NFT.
Properties
operator
address
The address of the operator. This is necessary because if the order creator is a gallery (i.e., the commission receiver), they wouldn't be able to cancel or update the order without knowing whether the order creator was the seller or the commissionReceiver.
seller
address
collection
address
bidder
address
The address of the highest bidder. This address must be payable to receive a refund in case of being outbid.
tokenId
uint256
bidPrice
uint256
end
uint256
The time at which this auction will stop accepting any new bids. This is 0 until the first bid is placed.
commissionBps
uint256[]
commissionReceivers
address[]
Last updated