Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

Revolutionizing Digital Asset Trading: The Ultimate NFT Marketplace on BTTC | by BitTorrent Inc. | Sep, 2024

[

]

BitTorrent Inc.

Welcome to the future of digital asset trading! Today, we are diving into the intricacies of a decentralized NFT marketplace built on the BitTorrent Chain (BTTC). This marketplace is designed to facilitate the trading of Non-Fungible Tokens (NFTs), integrating auction mechanisms, transaction fees, and robust security features. Whether you’re a creator, collector, or trader, this contract provides a secure and transparent environment for all your NFT transactions.

The MarketPlace contract is a comprehensive solution for managing NFT transactions. It supports the creation and management of sell orders, bidding on NFTs, and the execution of trades. Let’s break down the key components and functionalities of this contract.

The contract defines several state variables and data structures to manage orders, bids, and administrative settings:

using SafeERC20 for IERC20;
uint256 private _orderIds;
uint256 private _bidIds;

address public _adminAddress = ””;

// To store commission percentage for each mint
uint8 private _adminCommissionPercentage = 25;

// Mapping from token to the current ask for the token
mapping(uint256 => IUtils.Order) private _orders;

// Mapping from token to the current ask for the token
mapping(uint256 => IUtils.Bid) private _bids;

mapping(address => bool) public approvedCurrency;

mapping(address => bool) public approvedNfts;

uint256 private constant EXPO = 1e18;
uint256 private constant BASE = 1000 * EXPO;

Administrative Functions

These functions allow the admin to manage various aspects of the marketplace:

  • Set Admin Address: Updates the admin wallet where all commissions will go.
function setAdminAddress(address _newAdminWallet) external override returns (bool) {
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Caller is not a admin");
require(_newAdminWallet != address(0), "Admin Wallet cannot be empty address");
emit UpdateAdminWallet(_adminAddress, _newAdminWallet);
_adminAddress = _newAdminWallet;
return true;
}
  • Set Commission Percentage: Updates the commission percentage of the admin.
function setCommissionPercentage(uint8 _commissionPercentage) external override returns (bool) {
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Caller is not a admin");
_adminCommissionPercentage = _commissionPercentage;
emit CommissionUpdated(_adminCommissionPercentage);
return true;
}
  • Update Currency: Updates the currency accepted for bidding.
function updateCurrency(address _tokenAddress, bool _status) external override returns (bool) {
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Caller is not a admin");
approvedCurrency[_tokenAddress] = _status;
return true;
}
  • Update NFT Contract: Adds a new NFT to the marketplace.
function updateNFTContract(address _tokenAddress, bool _status) external override returns (bool) {
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Caller is not a admin");
approvedNfts[_tokenAddress] = _status;
return true;
}

Order Management Functions

These functions handle the creation, management, and execution of orders:

  • Set Order: Creates a new sell order for an NFT.
function setOrder(address _nftContract, uint256 _tokenId, address _currency, uint256 _askAmount, uint256 _expiryTime)
whenNotPaused
external
override
{
_orderIds += 1;

require(approvedNfts[_nftContract], "NFT is not approved by admin");
require(approvedCurrency[_currency], "Currency is not approved by admin");
require(_askAmount > 0, "Ask Amount Cannot be Zero");
require(_expiryTime > block.timestamp, "Expiry Time cannot be in Past");
ERC721 nftContract = ERC721(_nftContract);
require(nftContract.ownerOf(_tokenId) == msg.sender, "You are not owner of Token Id");
bool isAllTokenApproved = nftContract.isApprovedForAll(_msgSender(), address(this));
address approvedSpenderOfToken = nftContract.getApproved(_tokenId);
require((isAllTokenApproved || approvedSpenderOfToken == address(this)), "Market Contract is not allowed to manage this Token ID");

uint256 currentOrderId = _orderIds;
IUtils.Order storage order = _orders[currentOrderId];

order.orderId = currentOrderId;
order.sender = _msgSender();
order.askAmount = _askAmount;
order.currency = _currency;
order.nftContract = _nftContract;
order.tokenId = _tokenId;
order.expiryTime = _expiryTime;
order.orderStatus = IUtils.OrderStatus.OPEN;
order.createdAt = block.timestamp;
order.updatedAt = block.timestamp;

emit OrderCreated(currentOrderId, order);
}

  • Get Order: Retrieves the details of a specific order by its ID.
function getOrder(uint256 _orderId) external override view returns (IUtils.Order memory) {
return _orders[_orderId];
}
Cancel Order: Allows the order creator or an admin to cancel an open order.
function cancelOrder(uint256 _orderId) whenNotPaused external override returns (bool) {
IUtils.Order storage order = _orders[_orderId];

require(order.sender != address(0), "Invalid Order Id");
require(order.orderStatus == IUtils.OrderStatus.OPEN, "Order status is not Open");
bool hasAdminRole = hasRole(DEFAULT_ADMIN_ROLE, _msgSender());
require(order.sender == _msgSender() || hasAdminRole, "You Don't have right to cancel order");

order.orderStatus = IUtils.OrderStatus.CANCELED;
emit OrderRemoved(_orderId, order);
return true;
}

  • Complete Order: Executes a purchase of an NFT based on an open order.
function completeOrder(uint256 _orderId) whenNotPaused external override returns (bool) {
IUtils.Order storage order = _orders[_orderId];

require(order.sender != address(0), "Invalid Order Id");
require(order.orderStatus == IUtils.OrderStatus.OPEN, "Order status is not Open");
IERC20 token = IERC20(order.currency);
ERC721 nft = ERC721(order.nftContract);
require(block.timestamp <= order.expiryTime, "Order is expired");
require(token.balanceOf(_msgSender()) >= order.askAmount, "Not enough funds available to buy");
require(token.allowance(_msgSender(), address(this)) >= order.askAmount, "Please Approve Tokens Before You Buy");

uint256 _amountToDistribute = order.askAmount;
uint256 adminCommission = (_amountToDistribute * (_adminCommissionPercentage * EXPO)) / (BASE);
uint256 _amount = _amountToDistribute - adminCommission;

token.safeTransferFrom(_msgSender(), _adminAddress, adminCommission);
token.safeTransferFrom(_msgSender(), order.sender, _amount);
nft.transferFrom(order.sender, _msgSender(), order.tokenId);

order.orderStatus = IUtils.OrderStatus.COMPLETED;
order.recipient = _msgSender();
emit OrderCompleted(order.orderId, order);
return true;
}

Bid Management Functions

These functions handle the creation, management, and execution of bids:

  • Add Bid: Allows users to place bids on NFTs.
function addBid(address _nftContract, uint256 _tokenId, address _currency, uint256 _bidAmount, uint256 _expiryTime)
whenNotPaused
external
override
{
_bidIds += 1;

require(approvedNfts[_nftContract], "NFT is not approved by admin");
require(approvedCurrency[_currency], "Currency is not approved by admin");
require(_bidAmount > 0, "Bid Amount Cannot be Zero");
require(_expiryTime > block.timestamp, "Expiry Time cannot be in Past");

ERC721 nft = ERC721(_nftContract);
require(nft.ownerOf(_tokenId) != msg.sender, "You Can't Bid on your Own Token");

IERC20 token = IERC20(_currency);
require(token.balanceOf(_msgSender()) >= _bidAmount, "Not enough funds available to add bid");
require(token.allowance(_msgSender(), address(this)) >= _bidAmount, "Please Approve Tokens Before You Bid");

uint256 currentBidId = _bidIds;
IUtils.Bid storage bid = _bids[currentBidId];

bid.bidId = currentBidId;
bid.sender = _msgSender();
bid.bidAmount = _bidAmount;
bid.currency = _currency;
bid.nftContract = _nftContract;
bid.tokenId = _tokenId;
bid.expiryTime = _expiryTime;
bid.bidStatus = IUtils.OrderStatus.OPEN;
bid.createdAt = block.timestamp;
bid.updatedAt = block.timestamp;

emit BidAdded(currentBidId, bid);
}

  • Cancel Bid: Allows the bidder, the NFT owner, or an admin to cancel an open bid.
function cancelBid(uint256 _bidId) whenNotPaused external override returns (bool) {
IUtils.Bid storage bid = _bids[_bidId];

require(bid.sender != address(0), "Invalid Bid Id");
require(bid.bidStatus == IUtils.OrderStatus.OPEN, "Bid status is not Open");
bool hasAdminRole = hasRole(DEFAULT_ADMIN_ROLE, _msgSender());

ERC721 nft = ERC721(bid.nftContract);
require(bid.sender == _msgSender() || nft.ownerOf(bid.tokenId) == _msgSender() || hasAdminRole, "You Don't have right to cancel bid");

bid.bidStatus = IUtils.OrderStatus.CANCELED;
emit BidRemoved(_bidId, bid);
return true;
}

  • Accept Bid: Allows the NFT owner to accept a bid, transferring the NFT to the bidder and the bid amount (minus commission) to the NFT owner.
function acceptBid(uint256 _bidId) whenNotPaused external override returns (bool) {
IUtils.Bid storage bid = _bids[_bidId];

require(bid.sender != address(0), "Invalid Bid Id");
require(bid.bidStatus == IUtils.OrderStatus.OPEN, "Bid status is not Open");
require(block.timestamp <= bid.expiryTime, "Bid is expired");

IERC20 token = IERC20(bid.currency);
ERC721 nft = ERC721(bid.nftContract);
require(nft.ownerOf(bid.tokenId) == msg.sender, "You are not owner of Token Id");

require(token.balanceOf(bid.sender) >= bid.bidAmount, "Bidder doesn't have Enough Funds");
require(token.allowance(bid.sender, address(this)) >= bid.bidAmount, "Bidder has not Approved Tokens");

bool isAllTokenApproved = nft.isApprovedForAll(_msgSender(), address(this));
address approvedSpenderOfToken = nft.getApproved(bid.tokenId);
require((isAllTokenApproved || approvedSpenderOfToken == address(this)), "Market Contract is not allowed to manage this Token ID");

uint256 _amountToDistribute = bid.bidAmount;
uint256 adminCommission = (_amountToDistribute * (_adminCommissionPercentage * EXPO)) / (BASE);
uint256 _amount = _amountToDistribute - adminCommission;

nft.transferFrom(_msgSender(), bid.sender, bid.tokenId);
token.safeTransferFrom(bid.sender, _adminAddress, adminCommission);
token.safeTransferFrom(bid.sender, _msgSender(), _amount);

bid.bidStatus = IUtils.OrderStatus.COMPLETED;
bid.recipient = _msgSender();
emit BidAccepted(bid.bidId, bid);
return true;
}

The MarketPlace contract is a comprehensive solution for managing NFT transactions. By leveraging the power of smart contracts, it ensures transparency, security, and efficiency in the trading process. Whether you’re minting new NFTs, bidding on unique digital assets, or managing a marketplace, this contract provides the tools you need to succeed in the dynamic world of blockchain-based digital assets.

Github URL:
https://github.com/adeelch9/bttc-examples/tree/master/projects/nft-marketplace

[

]

Source link

Leave a Reply

Your email address will not be published. Required fields are marked *