NFT Auction
Implementing basic TON NFT auction functionality
Architecture
Leveraging the advantages of TON parent-child contracts, NFT holders create a dedicated NFT Auction Contract through the NFT Auction Market Contract for auctioning.
Auction Mechanics
- This smart contract interface can be used for NFT auctions (or just buying/selling) in a decentralized and flexible manner.
- Sellers and bidders are able to create customized auctions and bids, enabling a comprehensive NFT auction/selling mechanism.
Seller Actions
Auction Customization- NFTAddress
: The address of the NFT being auctioned.
reservePrice
: The auction begins when this price is reached, and users have a specific period of time to make subsequent higher bids. IfbuyNowPrice
is also set, the reserve price cannot be higher than thebuyNowPrice
.buyNowPrice
: The auction automatically ends when a buyer reaches this price.auctionEnd
: The deadline for this NFT auction bidding.defaultAuctionBidPeriod
: Specifies the duration of the auction after reaching the reserve price. Each time a higher bid is reached, the auction will continue for this period again. For example, if the auction bid period is set to x, and the reserve price is reached at time T0, the auction will end at time T0+x. However, if a higher bid is made at time T1 (where T0 < T1 < T0+x) by another bidder, the auction end time will be updated to T1 +x.defaultBidIncreasePercentage
: It determines the amount a bidder must deposit to become the highest bidder. Therefore, if the bid amount is X, the next bidder must bid X + ((X * bid increase percentage)/10000).beneficiary
: TheAddress
specified to receive the auction proceeds when the auction ends.
message SetUpAuction {
nftAddress: Address; // NFT address to be auctioned
reservePrice: Int as coins; // minimum bid price to start the auction timer
buyNowPrice: Int as coins; // price at which the NFT can be directly bought
auctionPeriod: Int as uint256; // time when the auction ends after it starts
beneficiary: Address?; // the address of the beneficiary
}
Bidder Actions
Auction Participation
bidValue
: If there is already a bid, bidders must bid a higher amount by the bid increase percentage. But if this is already satisfied, bidders don't need to bid higher than the seller's set reserve price (in this case, the auction will not start). Therefore, if there are no bids on the auction, bidders can specify any amount.- Users can also make custom bids, specifying an NFT recipient, and if their bid is successful, the NFT will be transferred to that recipient.
Direct Purchase
- In this case, buyers can bid an amount less than the buy-now price, which will not end the sale. Then, buyers must bid an amount higher by the default percentage than the previous lower bid. If the bidder specifies an amount equal to or higher than the buy-now price, the sale will end, and the NFT and purchase amount will be transferred.
Additional functions available
Sellers can:
- Withdraw their auction if the reserve price has not been met or at any time during the sale.
- Update the auction's reserve price. This action can only be done if there have been no bids exceeding the original reserve price.
- Update the buy-now price for the auction or sale. If there has been a bid on the auction or sale, and this update would mean this bid now meets the buy-now price, the auction or sale will end, and the NFT and bid amount will be allocated accordingly.
- Accept the highest bid amount and end the auction or sale.
Bidders can:
- Anyone can settle the auction and distribute the bids and NFT to the respective seller and recipient once the auction bid period has passed (the reserve bid has been met).
- When a bidder's
bidValue
is surpassed by a new bidder'sbidValue
, the previous bid'sbidValue
is returned to the bidder, and the new highest bid price and bidder are updated. - The seller of the NFT cannot bid on their own NFT auction.
Let's TON it up!!!
With NFTAuctionMarketStandard
Github Repo: https://github.com/Ton-Dynasty/tondynasty-contracts
trait NFTAuctionMarketStandard {
owner: Address;
// Check whether nft is transferred to NFT Auction Market Contract
auctionTransferCheck: map<Int, Int>; // key => hash(sellerAddress and nftAddress), value => 1: set, 0: not set
// Check whether nft auction is over or not
auctionOverCheck: map<Address, Address>; // key => nft auction contract address, value => 1: not over, 0: over
// @dev Default parameters for setting up an NFT auction
virtual const defaultBidIncreasePercentage: Int = 100;
virtual const defaultAuctionBidPeriod: Int = 86400; // 1 day
virtual const minimumSettableIncreasePercentage: Int = 100;
virtual const maximumMinPricePercentage: Int = 8000;
}
Quickly implement your own Auction Contract by inheriting NFTAuctionMarketStandard
, with the flexibility to rewrite default basic bidding variables.
Seller's Initial NFT Transfer
// @dev Processes the OwnershipAssigned message and updates auction mappings,
// and confirms NFT transfer to the Auction Market.
receive(msg: OwnershipAssigned) {
let ctx: Context = context();
let prev_owner: Address = msg.prev_owner; // Seller Address
let nftAddress: Address = ctx.sender;
let hashSellerNftAddress: Int = self.get_hash_seller_nft_address(prev_owner, nftAddress);
// Set nft transfer checking to 1
self.auctionTransferCheck.set(hashSellerNftAddress, 1);
let payload: Slice = msg.forward_payload;
if(payload.empty() == false) {
self._parse_forward_payload(prev_owner, nftAddress, payload);
}
}
- The Seller sends a
Transfer
message to the NFT Item. When the NFT Owner changes to the Auction Market, the NFT Item will send anOwnershipAssigned
message to the Auction Market Contract. Upon receiving the message, the Auction Contract will record the transfer as successful. - The Seller can use the
OwnershipAssigned
message'scustom_payload
to fill in the basic function ofSetUpAuction
. Ifcustom_payload
is filled in, it will also Deploy the NFT Auction Contract for the Seller simultaneously. - If `custom
_payloadis not filled in, you can send a
SetUpAuction` message to the NFT Auction Market contract again and Deploy the NFT Auction Contract.
// @dev Handles the receipt of a SetUpAuction message.
// First, it verifies if the NFT has been transferred to the NFT Auction Market Contract.
// Upon successful validation, it sets up the auction for the specified NFT and deploys
// a new NFT Auction Contract instance for it.
receive(msg: SetUpAuction) {
let ctx: Context = context();
let sellerAddress: Address = ctx.sender;
let hashSellerNftAddress: Int = self.get_hash_seller_nft_address(sellerAddress, msg.nftAddress);
self._auction_transfer_validate(hashSellerNftAddress);
if(msg.beneficiary == null) {
msg.beneficiary = sellerAddress;
}
// Set up auction info
let auctionInfo: AuctionInfo = self._set_up_auction(sellerAddress, msg.nftAddress, msg.reservePrice, msg.N, msg.auctionPeriod, msg.beneficiary!!); // set up auction
self._set_price_validate(msg.buyNowPrice, msg.reservePrice);
let nftAuctionInit: StateInit = self._nft_auction_init(msg.nftAddress, sellerAddress);
let nftAuctionAddress: Address = self.get_nft_auction_address(msg.nftAddress, sellerAddress);
self._auction_set_validate(nftAuctionAddress);
self.auctionOverCheck.set(nftAuctionAddress, msg.nftAddress);
// Deploy a new NFT Auction Contract
self._build_auction(nftAuctionAddress, auctionInfo, nftAuctionInit);
}
Post-Auction Contract Establishment
- Bidders can send a
Bid
message to the NFT Auction Contract, bidding on this NFT, wheremessage.value
is the bid price. - Upon receiving the
Bid
message, the Auction Market will first check if this auction is still active or not.
// Check if auction is still active.
require(now() < self.auctionEndTime || self.auctionEndTime == 0, "Auction ended");
require(self.isInitialized == 1, "Contract is not initialized");
require((now() < self.auctionBidPeriod) |(self.auctionBidPeriod == 0), "Auction bid period ended");
- Check if
bidValue
exceedsbuyNowPrice
let bidValue: Int = ctx.value;
let buyNowPrice: Int = self.auctionInfo.buyNowPrice;
if(bidValue >= buyNowPrice) {
self.auctionInfo.nftHighestBid = bidValue;
// Pay winning bid amount to seller.
self._send_winning_bid_amount();
// Transfer NFT to buyer
self._transfer_nft(buyer);
self.isInitialized = 0;
return;
}
- If it doesn't exceed the direct purchase price, it will check if it exceeds the minimum increase percentage of the current highest bid
let bidIncreaseAmount: Int = (self.auctionInfo.nftHighestBid * (10000 + self.auctionInfo.bidIncreasePercentage)) / 10000;
require(bidValue > bidIncreaseAmount, "Bid doesn't meet the minimum increase requirement");
- If it exceeds the increase percentage, the Previous Highest Bid Value will be returned to the Previous Highest Bidder.
// Send back previous highest bid to previous highest bidder.
let prevNftHighestBidder: Address = self.auctionInfo.nftHighestBidder;
let prevNftHighestBid: Int = self.auctionInfo.nftHighestBid;
let paybackTon: Int = max(prevNftHighestBid - self.minTonsForStorage - self.gasConsumption,0);
send(SendParameters{
to: prevNftHighestBidder,
value: paybackTon,
mode: SendPayGasSeparately,
bounce: false,
body: "Pay bid money back to the prevNftHighestBidder".asComment()
});
- Update Highest Bid, Bidder, and Auction Bid Period
// Update highest bid and Transfer ton back to previous highest bidder.
self.auctionInfo.nftHighestBidder = ctx.sender;
self.auctionInfo.nftHighestBid = bidValue;
// If bid value is greater than reserve price, then the auction is being started.
if(bidValue > self.auctionInfo.reservePrice) {
self._update_auction_bid_period();
if(self.auctionEndTime == 0) {
// If the auction start, then set the auction end time.
self._update_auction_end_time();
}
}
Settling the NFT Auction
- If the Auction Bid Period ends without anyone offering a higher bid, anyone can send a settlement Message to the Autction contract.
- If the Auction has already started (the bid has already exceeded the
reservePrice
), theBidValue
will be sent to the Seller after the Auction ends, and the NFT will be transferred to the Bidder. - If the Auction has not started, the NFT will be returned to the Seller.
// @dev Ends the auction and transfers the NFT to the highest bidder or back to the seller(If auction not started)
receive("EndAuction") {
// If this auction started, it will transfer NFT to highest bidder.
// Else, it will transfer NFT to seller.
if(self.auctionEndTime > 0) {
// Pay royalty to the creator of the NFT
// TODO: Implement royalty payment
// Pay winning bid amount to seller.
self._send_winning_bid_amount();
// Transfer NFT to buyer
let buyer: Address = self.auctionInfo.nftHighestBidder;
self._transfer_nft(buyer);
self.isInitialized = 0;
}
else {
// Transfer NFT to seller
let seller: Address = self.auctionInfo.nftSeller;
self._transfer_nft(seller);
self.isInitialized = 0;
}
}
- Transfer NFT to the new Owner
- Send
TransferNFT
Message to NFT Auction Contract, then transfer NFT to the new Owner
// @dev Transfer the NFT to the highest bidder
// @note If you want change msg value, you should make sure that is enough for NFT Auction market contract to transfer NFT.
virtual inline fun _transfer_nft(buyer: Address) {
send(SendParameters{
to: self.owner,
value: ton("0.06"),
bounce: true,
mode: SendPayGasSeparately,
body: TransferNFT {
nftAddress: self.nftAddress,
seller: self.auctionInfo.nftSeller,
query_id: 0,
new_owner: buyer,
response_destination: buyer,
custom_payload: emptyCell(),
forward_amount: 0,
forward_payload: emptySlice()
}.toCell()
});
}
Upon receiving the NFT transfer message, the NFT
Auction Contract sends a
Transfer
message to the NFT Item to change the Owner
// @dev Handles the TransferNFT message and facilitates NFT transfer to the auction's winning bidder.
receive(msg: TransferNFT) {
let ctx: Context = context();
let nftAuctionAddress: Address = ctx.sender;
self._auction_not_set_validate(nftAuctionAddress);
send(SendParameters{
to: msg.nftAddress,
value: 0,
bounce: false,
mode: SendRemainingValue,
body: Transfer {
query_id: msg.query_id,
new_owner: msg.new_owner,
response_destination: msg.response_destination,
custom_payload: msg.custom_payload,
forward_amount: msg.forward_amount,
forward_payload: msg.forward_payload
}.toCell()
});
self.auctionOverCheck.set(ctx.sender, null);
let hashSellerNftAddress: Int = self.get_hash_seller_nft_address(msg.seller, msg.nftAddress);
self.auctionTransferCheck.set(hashSellerNftAddress, null);
}
## <a id="auction-example-code"></a>Auction Example Code
- NFT Auction Market Trait Link: <https://github.com/Ton-Dynasty/tondynasty-contracts/blob/main/contracts/packages/token/nft/NFTAuctionMarket.tact>
- NFT Auction Trait Link: <https://github.com/Ton-Dynasty/tondynasty-contracts/blob/main/contracts/packages/token/nft/NFTAuction.tact>
```ts
import "@stdlib/deploy";
import "./packages/token/nft/NFTAuctionMarket";
import "./packages/token/nft/NFTAuction";
contract ExampleNFTAuctionMarket with Deployable, NFTAuctionMarketStandard {
owner: Address;
// Get auction info by seller address and nft address.
nftContractAuctions: map<Int, AuctionInfo>; // key => hash(sellerAddress and nftAddress), value => AuctionInfo
// Check whether nft is transfered to NFT Auction Market Contract
auctionTransferCheck: map<Int, Int>; // key => hash(sellerAddress and nftAddress), value => 1: set, 0: not set
// Get auction info by nft collection address and nft id.
collectionNftIdToAuction: map<Int, Int>; // key => hash(nft collection address and nft id), value => hash(sellerAddress and nftAddress)
// Check whether nft auction is over or not
auctionOverCheck: map<Address, Address>; // key => nft auction contract address, value => 1: not over, 0: over
init(owner: Address) {
self.owner = owner;
}
// @dev Retrieves the initial state for the NFT auction contract.
override get fun _nft_auction_init(nftAddress: Address, seller: Address): StateInit {
return initOf ExampleNFTAuction(myAddress(), nftAddress, seller);
}
}
contract ExampleNFTAuction with NFTAuctionStandard {
owner: Address;
nftAddress: Address;
seller: Address;
auctionInfo: AuctionInfo;
auctionBidPeriod: Int;
isInitialized: Int;
auctionEndTime: Int;
init(owner: Address, nftAddress: Address, seller: Address) {
self.owner = owner;
self.nftAddress = nftAddress;
self.seller = seller;
self.auctionBidPeriod = 0;
self.auctionEndTime = 0;
self.isInitialized = 0;
self.auctionInfo = AuctionInfo {
bidIncreasePercentage: 0,
auctionBidPeriod: 0,
auctionPeriod: 0,
reservePrice: 0,
buyNowPrice: 0,
nftHighestBid: 0,
nftHighestBidder: newAddress(0, 0),
nftSeller: seller,
whitelistedBuyer: seller,
nftRecipient: seller,
beneficiary: seller
};
}
}
Additional Functions
Revise SetUp Auction
- If the auction has not yet started, the Seller can change the
reserve_price
andbuyNowPrice
. - Send a
ReviseSetUpAuction
message to the NFT Auction Market.
// @dev Updates auction details after verifying NFT transfer and previous auction setup, then communicates the update to the nftAuctionAddress.
receive(msg: ReviseSetUpAuction) {
let ctx: Context = context();
let sellerAddress: Address = ctx.sender;
let hashSellerNftAddress: Int = self.get_hash_seller_nft_address(sellerAddress, msg.nftAddress);
self._auction_transfer_validate(hashSellerNftAddress);
// Get nft auction address
let nftAuctionAddress: Address = self.get_nft_auction_address(msg.nftAddress, sellerAddress);
self._auction_not_set_validate(nftAuctionAddress);
if(msg.beneficiary == null) {
msg.beneficiary = sellerAddress;
}
// Set up auction info
let auctionInfo: AuctionInfo = self._set_up_auction(sellerAddress, msg.nftAddress, msg.reservePrice, msg.buyNowPrice, msg.auctionPeriod, msg.beneficiary!!); // set up auction
self.auctionOverCheck.set(nftAuctionAddress, msg.nftAddress);
let newAuctionInfo: AuctionInfo = self._set_up_auction(sellerAddress, msg.nftAddress, msg.reservePrice, msg.buyNowPrice, msg.auctionPeriod, msg.beneficiary!!); // set up auction
send(SendParameters{
to: nftAuctionAddress,
value: 0,
mode: SendRemainingValue,
bounce: false,
body: ReviseAuction {
reviseAuctionInfo: newAuctionInfo
}.toCell()
}
);
}
- The NFT Auction Market will send a modification message to the NFT Auction Contract.
// @dev Allows owner to adjust auction's reserve or buy-now prices.
receive(msg: ReviseAuction) {
let ctx: Context = context();
require(ctx.sender == self.owner, "Only owner can revise auction contract");
require(self.auctionInfo.reservePrice == msg.reviseAuctionInfo.reservePrice || msg.reviseAuctionInfo.buyNowPrice == self.auctionInfo.buyNowPrice, "Cannot update reserve price and buy now price at the same time.");
// Update the reserve price of the auction.
// This can only be done if no bid has been made that already exceeds the original minimum price.
if(self.auctionEndTime == 0 && self.auctionInfo.reservePrice != msg.reviseAuctionInfo.reservePrice && msg.reviseAuctionInfo.reservePrice < self.auctionInfo.buyNowPrice) {
self.auctionInfo.reservePrice = msg.reviseAuctionInfo.reservePrice;
if(self.auctionInfo.nftHighestBid > self.auctionInfo.reservePrice) {
self._update_auction_bid_period();
self._update_auction_end_time();
}
}
// Update the buy now price of the auction.
// This can only be done if no bid has been made that already exceeds the original minimum price.
if(self.auctionEndTime == 0 && msg.reviseAuctionInfo.buyNowPrice != self.auctionInfo.buyNowPrice && msg.reviseAuctionInfo.buyNowPrice > self.auctionInfo.reservePrice) {
self.auctionInfo.buyNowPrice = msg.reviseAuctionInfo.buyNowPrice;
}
}
EndAuction
- If the Seller wants to terminate the auction early, they can send an
EndAuction
message to the NFT Auction Market.
// @dev Allows the seller to terminate an auction.
// It verifies if the auction was previously set and then sends a message to the nftAuctionAddress to conclude the auction.
// It will transfer the NFT to the highest bidder or back to the seller(If auction not started).
receive(msg: EndAuction) {
// Seller can end auction.
let ctx: Context = context();
let sellerAddress: Address = ctx.sender;
let hashSellerNftAddress: Int = self.get_hash_seller_nft_address(sellerAddress, msg.nftAddress);
let nftAuctionAddress: Address = self.get_nft_auction_address(msg.nftAddress, sellerAddress);
self._auction_not_set_validate(nftAuctionAddress);
send(SendParameters{
to: nftAuctionAddress,
value: 0,
mode: SendRemainingValue,
bounce: false,
body: "EndAuction".asComment()
}
);
}
- If the auction has already started, it will immediately conclude and send the NFT to the current Highest Bidder, and the
BidValue
will be sent to the Seller. - If the auction has not started, the NFT will be returned to the Seller.
// @dev Ends the auction and transfers the NFT to the highest bidder or back to the seller(If auction not started)
receive("EndAuction") {
// If this auction started, it will transfer NFT to highest bidder.
// Else, it will transfer NFT to seller.
if(self.auctionEndTime > 0) {
// Pay royalty to the creator of the NFT
// TODO: Implement royalty payment
// Pay winning bid amount to seller.
self._send_winning_bid_amount();
// Transfer NFT to buyer
let buyer: Address = self.auctionInfo.nftHighestBidder;
self._transfer_nft(buyer);
self.isInitialized = 0;
}
else {
// Transfer NFT to seller
let seller: Address = self.auctionInfo.nftSeller;
self._transfer_nft(seller);
self.isInitialized = 0;
}
}
Auction Market Contract Internal Functions && Get Methods
Internal Function:
// @dev Parses payload to extract auction parameters and initializes the auction with provided data.
virtual inline fun _parse_forward_payload(seller: Address, nftAddress: Address, payload: Slice) {
// Parse payload
let beneficiary: Address = payload.loadAddress();
let reservePrice: Int = payload.loadCoins();
let buyNowPrice: Int = payload.loadCoins();
let auctionPeriod: Int = payload.loadUint(256);
// Set up auction info
let auctionInfo: AuctionInfo = self._set_up_auction(seller, nftAddress, reservePrice, buyNowPrice, auctionPeriod, beneficiary); // set up auction
self._set_price_validate(buyNowPrice, reservePrice);
let nftAuctionInit: StateInit = self._nft_auction_init(nftAddress, seller);
let nftAuctionAddress: Address = self.get_nft_auction_address(nftAddress, seller);
self._auction_set_validate(nftAuctionAddress);
self.auctionOverCheck.set(nftAuctionAddress, nftAddress);
// Deploy a new NFT Auction Contract
self._build_auction(nftAuctionAddress, auctionInfo,
nftAuctionInit);
}
// @dev Create and configure a new NFT Auction Contract with the provided auction info.
virtual inline fun _build_auction(nftAuctionAddress: Address, auctionInfo: AuctionInfo, nftAuctionInit: StateInit) {
send(SendParameters{
to: nftAuctionAddress,
value: 0,
mode: SendRemainingValue,
bounce: false,
body: BuildNftAuction {
auctionInfo: auctionInfo
}.toCell(),
code: nftAuctionInit.code,
data: nftAuctionInit.data
}
);
}
// @dev Validates that the buyNowPrice is higher than the reservePrice.
virtual inline fun _set_price_validate(buyNowPrice: Int, reservePrice: Int) {
require(buyNowPrice > reservePrice, "BuyNowPrice must be greater than reservePrice.");
}
// @dev Checks if an auction has already been set for the provided NFT address.
virtual inline fun _auction_set_validate(nftAuctionAddress: Address) {
require(self.auctionOverCheck.get(nftAuctionAddress) == null, "Auction was already set for this NFT.");
}
// @dev Validates that an auction was previously set for the given NFT address.
virtual inline fun _auction_not_set_validate(nftAuctionAddress: Address) {
require(self.auctionOverCheck.get(nftAuctionAddress) != null, "Auction was not set before.");
}
// @dev Verifies that the NFT was transferred to the auction contract.
virtual inline fun _auction_transfer_validate(hashSellerNftAddress: Int) {
require(self.get_is_auction_transfer_check(hashSellerNftAddress) == 1, "This NFT didn't transfer to NFT Auction Market Contract yet.");
}
// @dev Initializes an auction for a specified NFT with given parameters such as reserve price, buy now price, and auction duration.
// @note If you want to use custom auction parameters or logic, consider overriding this function and AuctionInfo struct in a derived contract.
virtual inline fun _set_up_auction(sellerAddress: Address, nftAddress: Address, reservePrice: Int, buyNowPrice: Int, auctionPeriod: Int, beneficiary: Address): AuctionInfo {
let hashSellerNftAddress: Int = self.get_hash_seller_nft_address(sellerAddress, nftAddress);
return AuctionInfo {
bidIncreasePercentage: self.defaultBidIncreasePercentage,
auctionBidPeriod: self.defaultAuctionBidPeriod,
auctionPeriod: auctionPeriod,
reservePrice: reservePrice,
buyNowPrice: buyNowPrice,
nftHighestBid: 0,
nftHighestBidder: sellerAddress,
nftSeller: sellerAddress,
whitelistedBuyer: sellerAddress,
nftRecipient: sellerAddress,
beneficiary: beneficiary
};
}
To know the parameters required for the NFT Auction's Init, you need to refer to the example of _nft_auction_init which can be found in the Auction Example Code.
// @dev Retrieves the initial state for the NFT auction contract.
// @note one MUST override this function to provide NFT Auction initCode
abstract fun _nft_auction_init(nftAddress: Address, seller: Address): StateInit;
Get Methods:
// @dev Determines the NFT auction contract address.
get fun get_nft_auction_address(nftAddress: Address, seller: Address): Address {
let nftAuctionInit: StateInit = self._nft_auction_init(nftAddress, seller);
return contractAddress(nftAuctionInit);
}
// @dev Generates a hash value based on the seller and NFT address.
get fun get_hash_seller_nft_address(seller: Address, nftAddress: Address): Int {
return beginCell().storeAddress(seller).storeAddress(nftAddress).endCell().asSlice().hash();
}
// @dev Checks if the auction transfer for a given hash is valid.
get fun get_is_auction_transfer_check(hashSellerNftAddress: Int): Int {
if(self.auctionTransferCheck.get(hashSellerNftAddress) == null) {
return 0;
}
else {
return 1;
}
}
Auction Contract Internal Functions && Get Methods
Internal Function:
// @dev Updates the auction bid period time based on the latest bid and the defined auction bid period
virtual inline fun _update_auction_bid_period() {
self.auctionBidPeriod = now() + self.auctionInfo.auctionBidPeriod;
}
// @dev Updates the auction end time
virtual inline fun _update_auction_end_time() {
self.auctionEndTime = now() + self.auctionInfo.auctionPeriod;
}
// @dev Transfer the NFT to the highest bidder
// @note If you want change msg value, you should make sure that is enough for NFT Auction market contract to transfer NFT.
virtual inline fun _transfer_nft(buyer: Address) {
send(SendParameters{
to: self.owner,
value: ton("0.06"),
bounce: true,
mode: SendPayGasSeparately,
body: TransferNFT {
nftAddress: self.nftAddress,
seller: self.auctionInfo.nftSeller,
query_id: 0,
new_owner: buyer,
response_destination: buyer,
custom_payload: emptyCell(),
forward_amount: 0,
forward_payload: emptySlice()
}.toCell()
});
}
// @dev Transfers the highest bid amount to the seller
virtual inline fun _send_winning_bid_amount() {
let seller: Address = self.auctionInfo.beneficiary;
let winningBidAmount: Int = self.auctionInfo.nftHighestBid;
send(SendParameters{
to: seller,
value: winningBidAmount - ton("0.06"),
mode: SendPayGasSeparately,
bounce: false,
body: "Pay winning bid amount".asComment()
});
}
// @dev Initializes the auction end time to 0, allowing the seller to auction the NFT again in the future
virtual inline fun _init_auction_end() {
let ctx: Context = context();
require(ctx.sender == self.owner, "Only owner can init auction end time.");
self.auctionBidPeriod = 0;
}
Get Methods
// @dev Returns the current auction information
get fun get_auction_info(): AuctionInfo {
return self.auctionInfo;
}
// @dev Checks if the auction is initialized and returns the state (1 for initialized, 0 otherwise)
get fun get_is_initialized(): Int {
return self.isInitialized;
}
// @dev Returns the end time of the auction
get fun get_auction_end(): Int {
return self.auctionEndTime;
}
// @dev Returns the auction bid period
get fun get_auction_bid_period(): Int {
return self.auctionBidPeriod;
}