- NFT token is always listed, even after sale (just the owner is changed)
- the marketplace contract IS NOT holding/owning the listed NFT token
- after sale, the price of the token is increased by sale price + 20%, so the new owner doesn't need to list it
- if the new owner doesn't want that behavior, it should cancel the order
- the new owner cannot update the price to be lower than the sale price +20%
- the new owner can update the price to be higher than the sale price +20%
- only a new owner of the token can update the price to be lower
listing price cannot be lower than general floor price which increases after each sale
Last active
August 29, 2022 23:07
-
-
Save tunnckoCore/c1704dcd04c695802b7ee084bd74452f to your computer and use it in GitHub Desktop.
Perpetual NFT Marketplace, with increasing token price - cannot list it for less than the last sale + 20% (configurable)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: GPL-3.0 | |
pragma solidity >=0.7.0 <0.9.0; | |
interface IERC721 { | |
function ownerOf(uint256 tokenId) external view returns (address owner); | |
function transferFrom(address from, address to, uint256 tokenId) external; | |
function isApprovedForAll(address owner, address operator) external view returns (bool); | |
} | |
contract Marketplace { | |
mapping(IERC721 => mapping(uint256 => uint256)) public orders; | |
mapping(IERC721 => mapping(uint256 => address)) public sellers; | |
function createOrder(IERC721 nftContract, uint256 tokenId, uint256 price) public { | |
require(IERC721(nftContract).ownerOf(tokenId) == msg.sender, "BasicMarketplace: not owner of token"); | |
require(IERC721(nftContract).isApprovedForAll(msg.sender, address(this)), "approve the marketplace contract first"); | |
if (price != 0) { | |
require(price > orders[nftContract][tokenId], "new price must be higher than current order price"); | |
} | |
orders[nftContract][tokenId] = price; | |
sellers[nftContract][tokenId] = msg.sender; | |
} | |
function bulkList(IERC721 nftContract, uint256[] memory tokenIds, uint256[] memory prices) public { | |
require(IERC721(nftContract).isApprovedForAll(msg.sender, address(this)), "approve the marketplace contract first"); | |
for(uint i=0; i< tokenIds.length; i++) { | |
uint256 id = tokenIds[i]; | |
uint256 price = prices[i]; | |
require(IERC721(nftContract).ownerOf(id) == msg.sender, "BasicMarketplace: not owner of token"); | |
if (price != 0) { | |
require(price > orders[nftContract][id], "new price must be higher than current order price"); | |
} | |
orders[nftContract][id] = price; | |
sellers[nftContract][id] = msg.sender; | |
} | |
} | |
function fulfillOrder(IERC721 nftContract, uint256 tokenId) external payable { | |
require(IERC721(nftContract).ownerOf(tokenId) != msg.sender, "owner of token"); | |
uint256 price = orders[nftContract][tokenId]; | |
address seller = sellers[nftContract][tokenId]; | |
require(price != 0, "no opened order for this token"); | |
require(seller != address(0), "no seller for this token"); | |
require(seller != msg.sender, "cannot sell to yourself"); | |
require(price == msg.value, "invalid ask price"); | |
orders[nftContract][tokenId] = price + (price / 4); | |
sellers[nftContract][tokenId] = msg.sender; | |
// transfer the nft to the buyer | |
IERC721(nftContract).transferFrom(seller, msg.sender, tokenId); | |
// transfer ETH from the sender/contract to the seller | |
payable(seller).transfer(price); | |
} | |
function sweepOrders(IERC721 nftContract, uint256[] memory tokenIds) external payable { | |
uint256 sweepPrice = 0; | |
for(uint i=0; i< tokenIds.length; i++) { | |
sweepPrice += orders[nftContract][tokenIds[i]]; | |
} | |
require(sweepPrice == msg.value, "not enough funds for sweep"); | |
for(uint i=0; i< tokenIds.length; i++) { | |
uint256 tokenId = tokenIds[i]; | |
require(IERC721(nftContract).ownerOf(tokenId) != msg.sender, "owner of token"); | |
uint256 price = orders[nftContract][tokenId]; | |
address seller = sellers[nftContract][tokenId]; | |
require(price != 0, "no opened order for this token"); | |
require(seller != address(0), "no seller for this token"); | |
require(seller != msg.sender, "cannot sell to yourself"); | |
// require(price == msg.value, "invalid ask price"); | |
orders[nftContract][tokenId] = price + (price / 4); | |
sellers[nftContract][tokenId] = msg.sender; | |
// transfer the nft to the buyer | |
IERC721(nftContract).transferFrom(seller, msg.sender, tokenId); | |
payable(seller).transfer(price); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment