Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ### MAIN CONTRACT
- // SPDX-License-Identifier: MIT
- pragma solidity >=0.6.0 <0.8.0;
- import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721BurnableUpgradeable.sol";
- import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
- import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
- contract Woonkly is ERC721BurnableUpgradeable, AccessControlUpgradeable {
- using SafeMathUpgradeable for uint256;
- mapping (uint256 => uint256) private _tokens_price;
- mapping (uint256 => address payable) private _tokenCreator;
- mapping (uint256 => address payable) private _offers_marketplace;
- mapping (uint256 => uint256) private _offers_closeTimestamp;
- event OfferReceived(address indexed payer, uint256 tokenId, uint256 amount);
- event OfferAccepted(address indexed payer, uint256 tokenId);
- event OfferRejected(address indexed payer, uint256 tokenId);
- event OfferExpired(address indexed payer, uint256 tokenId);
- event OfferCancelled(address indexed payer, uint256 tokenId);
- uint256 private constant COMMISSION_EXPONENT = 4;
- address payable private _platformAddress;
- uint256 private _platformCommissionPercent;
- uint256 private _extensionTimePeriod;
- uint256 private _offerExpirationTime;
- modifier tokenExists(uint256 _tokenId) {
- require(_exists(_tokenId), "Woonkly: Id for this token does not exist.");
- _;
- }
- modifier onlyOwner(uint256 _tokenId) {
- require(_tokenCreator[_tokenId] == msg.sender, "Woonkly: You are not the owner of this token.");
- _;
- }
- modifier offerExist(uint256 _tokenId) {
- require(_offers_marketplace[_tokenId] != address(0), "Kargain: Does not exist any offer for this token.");
- _;
- }
- modifier onlyAdmin() {
- require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Woonkly: Caller is not a admin");
- _;
- }
- function initialize(address payable _platformAddress_, uint256 _platformCommissionPercent_) public initializer {
- _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
- __AccessControl_init();
- _offerExpirationTime = 1 days;
- _platformAddress = _platformAddress_;
- _platformCommissionPercent = _platformCommissionPercent_;
- __ERC721Burnable_init();
- __ERC721_init("Woonkly", "WKY");
- }
- function creatorOf(uint256 tokenId) external view returns (address payable) {
- require(_tokenCreator[tokenId] != address(0x0), "Woonkly: Creator query for nonexistent token");
- return _tokenCreator[tokenId];
- }
- function exist(uint256 _tokenId) external view returns (bool) {
- return _exists(_tokenId);
- }
- function offerExpirationTime() external view returns (uint256) {
- return _offerExpirationTime;
- }
- function setOfferExpirationTime(uint256 offerExpirationTime_) external onlyAdmin {
- _offerExpirationTime = offerExpirationTime_;
- }
- function platformCommissionPercent() external view returns (uint256) {
- return _platformCommissionPercent;
- }
- function setPlatformCommissionPercent(uint256 platformCommissionPercent_) external onlyAdmin {
- _platformCommissionPercent = platformCommissionPercent_;
- }
- function tokenPrice(uint256 _tokenId) external view tokenExists(_tokenId) returns (uint256) {
- return _tokens_price[_tokenId];
- }
- function setExtensionTimePeriod(uint256 extensionTimePeriod_) external onlyAdmin {
- _extensionTimePeriod = extensionTimePeriod_;
- }
- function extensionTimePeriod() public view returns(uint256){
- return _extensionTimePeriod;
- }
- function setTokenPrice(uint256 _tokenId, uint256 _price) external tokenExists(_tokenId) onlyOwner(_tokenId)
- {
- require(
- _offers_marketplace[_tokenId] == address(0) ||
- _offers_closeTimestamp[_tokenId] < now,
- "Woonkly: An offer is already submitted, token price cannot be changed until it expires."
- );
- _tokens_price[_tokenId] = _price;
- }
- function _refundOffer(uint256 _tokenId) private tokenExists(_tokenId) offerExist(_tokenId) {
- address payable buyer = _offers_marketplace[_tokenId];
- delete _offers_marketplace[_tokenId];
- delete _offers_closeTimestamp[_tokenId];
- buyer.transfer(_tokens_price[_tokenId]);
- }
- function createOffer(uint256 _tokenId) external payable tokenExists(_tokenId)
- {
- require(ownerOf(_tokenId) != msg.sender, "Woonkly: You cannot buy your own token.");
- require(_offers_marketplace[_tokenId] == address(0) && _offers_closeTimestamp[_tokenId] < now, "Woonkly: An offer is already submitted.");
- require(msg.value == _tokens_price[_tokenId], "Woonkly: The offer amount is invalid.");
- _offers_marketplace[_tokenId] = payable(msg.sender);
- _offers_closeTimestamp[_tokenId] = now.add(_offerExpirationTime);
- emit OfferReceived(msg.sender, _tokenId, msg.value);
- }
- function acceptOffer(uint256 _tokenId) external tokenExists(_tokenId) offerExist(_tokenId) onlyOwner(_tokenId) {
- if (_offers_closeTimestamp[_tokenId] < now) {
- delete _offers_marketplace[_tokenId];
- delete _offers_closeTimestamp[_tokenId];
- emit OfferExpired(msg.sender, _tokenId);
- return;
- }
- address payable buyer = _offers_marketplace[_tokenId];
- delete _offers_marketplace[_tokenId];
- delete _offers_closeTimestamp[_tokenId];
- uint256 platformCommission = _tokens_price[_tokenId].mul(_platformCommissionPercent).div(10**COMMISSION_EXPONENT);
- _platformAddress.transfer(platformCommission);
- msg.sender.transfer(_tokens_price[_tokenId].sub(platformCommission));
- safeTransferFrom(msg.sender, buyer, _tokenId);
- emit OfferAccepted(msg.sender, _tokenId);
- }
- function rejectOffer(uint256 _tokenId) external tokenExists(_tokenId) onlyOwner(_tokenId) offerExist(_tokenId) {
- _refundOffer(_tokenId);
- emit OfferRejected(msg.sender, _tokenId);
- }
- function mint(uint256 _tokenId, uint256 _price) external {
- require(!_exists(_tokenId), "Woonkly: Id for this token already exists.");
- require(_price > 0, "Woonkly: Prices must be greater than zero.");
- _mint(msg.sender, _tokenId);
- _tokenCreator[_tokenId] = msg.sender;
- _tokens_price[_tokenId] = _price;
- }
- }
- #### SECONDARY CONTRACT
- // SPDX-License-Identifier: MIT
- pragma solidity >=0.6.0 <0.8.0;
- import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721HolderUpgradeable.sol";
- import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
- import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
- import "./IWoonkly.sol";
- contract WoonklyAuction is ERC721HolderUpgradeable, AccessControlUpgradeable {
- using SafeMathUpgradeable for uint256;
- uint8 private constant COMMISSION_EXPONENT = 4;
- uint256 private _platformCommissionPercent;
- address payable private _platformAddress;
- uint256 private _extensionTimePeriod;
- mapping (IWoonkly => mapping (uint256 => uint256)) private _auction_closeTimestamp;
- mapping (IWoonkly => mapping (uint256 => address payable)) private _auction_bidder;
- mapping (IWoonkly => mapping (uint256 => uint256)) private _auction_amount;
- mapping (IWoonkly => mapping (uint256 => bool)) private _auction_claimed;
- mapping (IWoonkly => mapping (uint256 => bool)) private _auction_exist;
- mapping (IWoonkly => mapping (uint256 => uint256)) private _auction_platformCommissionPercent;
- mapping (IWoonkly => mapping (uint256 => address payable)) private _auction_vendor;
- event AuctionCreated(IWoonkly indexed token, uint256 indexed tokenId, uint256 closeTimestamp);
- event AuctionBid(IWoonkly indexed token, uint256 indexed tokenId, address indexed bidder, uint256 amount);
- event AuctionClaimed(IWoonkly indexed token, uint256 indexed tokenId, address indexed bidder, uint256 amount, uint256 platformCommision);
- modifier onlyAdmin() {
- require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Woonkly: Caller is not a admin");
- _;
- }
- function initialize(address payable _platformAddress_, uint256 _platformCommissionPercent_, uint256 extensionTimePeriod_) public initializer {
- _platformAddress = _platformAddress_;
- _platformCommissionPercent = _platformCommissionPercent_;
- _extensionTimePeriod = extensionTimePeriod_;
- __ERC721Holder_init();
- __AccessControl_init();
- _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
- }
- function setPlatformAddress(address payable platformAddress_) external onlyAdmin {
- _platformAddress = platformAddress_;
- }
- function platformAddress() public view returns(address payable){
- return _platformAddress;
- }
- function setPlatformCommissionPercent(uint256 platformCommissionPercent_) external onlyAdmin {
- _platformCommissionPercent = platformCommissionPercent_;
- }
- function platformCommissionPercent() public view returns(uint256){
- return _platformCommissionPercent;
- }
- function setExtensionTimePeriod(uint256 extensionTimePeriod_) external onlyAdmin {
- _extensionTimePeriod = extensionTimePeriod_;
- }
- function extensionTimePeriod() public view returns(uint256){
- return _extensionTimePeriod;
- }
- function ownerOfToken(IWoonkly tokenContract, uint256 tokenId) public returns(address) {
- return tokenContract.creatorOf(tokenId);
- }
- function auction(IWoonkly tokenContract, uint256 tokenId, uint256 secondsToClose) external {
- require(!_auction_exist[tokenContract][tokenId], "Woonkly: Auction for this token already exist");
- require(tokenContract.creatorOf(tokenId) == msg.sender, "You are not the owner of this token.");
- uint256 closeTimestamp = block.timestamp + secondsToClose;
- _auction_closeTimestamp[tokenContract][tokenId] = closeTimestamp;
- _auction_vendor[tokenContract][tokenId] = tokenContract.creatorOf(tokenId);
- _auction_platformCommissionPercent[tokenContract][tokenId] = _platformCommissionPercent;
- _auction_bidder[tokenContract][tokenId] = payable(address(0));
- _auction_amount[tokenContract][tokenId] = 0;
- _auction_claimed[tokenContract][tokenId] = false;
- _auction_exist[tokenContract][tokenId] = true;
- emit AuctionCreated(tokenContract, tokenId,closeTimestamp);
- }
- function placeBid(IWoonkly tokenContract, uint256 tokenId) external payable {
- require(_auction_exist[tokenContract][tokenId], "Woonkly: Auction for this token not exist");
- require(!_auction_claimed[tokenContract][tokenId], "Woonkly: Auction was claimed");
- require(_auction_closeTimestamp[tokenContract][tokenId] >= block.timestamp,
- "Woonkly: Auction for this token is closed");
- require(msg.value > _auction_amount[tokenContract][tokenId],
- "Woonkly: Bid should be higher than current");
- uint256 refundAmount = _auction_amount[tokenContract][tokenId];
- address payable refundAddress = _auction_bidder[tokenContract][tokenId];
- _auction_bidder[tokenContract][tokenId] = payable(address(msg.sender));
- _auction_amount[tokenContract][tokenId] = msg.value;
- // Extend close time if it's required
- uint256 bidTimeOffset = _auction_closeTimestamp[tokenContract][tokenId].sub(block.timestamp);
- if (bidTimeOffset < _extensionTimePeriod) {
- _auction_closeTimestamp[tokenContract][tokenId] = _auction_closeTimestamp[tokenContract][tokenId].add(
- _extensionTimePeriod.sub(bidTimeOffset)
- );
- }
- refundAddress.transfer(refundAmount);
- emit AuctionBid(tokenContract, tokenId, msg.sender, msg.value);
- }
- function claimAuction(IWoonkly tokenContract, uint256 tokenId) external onlyAdmin {
- require(_auction_exist[tokenContract][tokenId], "Woonkly: Auction not exist");
- require(!_auction_claimed[tokenContract][tokenId], "Woonkly: Auction was claimed");
- require(_auction_closeTimestamp[tokenContract][tokenId] < block.timestamp,
- "Woonkly: Auction is not closed");
- _auction_claimed[tokenContract][tokenId] = true;
- uint256 platformCommission;
- if (_auction_bidder[tokenContract][tokenId] != address(0)){
- platformCommission = _auction_amount[tokenContract][tokenId]
- .mul(_auction_platformCommissionPercent[tokenContract][tokenId])
- .div(10** COMMISSION_EXPONENT);
- tokenContract.safeTransferFrom(msg.sender, _auction_bidder[tokenContract][tokenId], tokenId);
- _platformAddress.transfer(platformCommission);
- _auction_vendor[tokenContract][tokenId].transfer(
- _auction_amount[tokenContract][tokenId].sub(platformCommission)
- );
- }
- else {
- tokenContract.burn(tokenId);
- }
- emit AuctionClaimed(tokenContract, tokenId, _auction_bidder[tokenContract][tokenId],
- _auction_amount[tokenContract][tokenId], platformCommission);
- }
- }
- #### INTERFACE
- //SPDX-License-Identifier: Unlicense
- pragma solidity >=0.6.0 <0.8.0;
- import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
- interface IWoonkly is IERC721Upgradeable {
- function mint(uint256 _tokenId, uint256 _price) external;
- function burn(uint256 tokenId) external;
- function creatorOf(uint256 tokenId) external view returns (address payable);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement