Instantly share code, notes, and snippets.
Created
September 7, 2023 14:20
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save Jayke770/5984c75a75fdfee4a780b94c4fbe6e6a to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.18+commit.87f61d96.js&optimize=false&runs=200&gist=
This file contains hidden or 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: MIT | |
| pragma solidity ^0.8.9; | |
| import "@openzeppelin/contracts@4.9.3/token/ERC721/ERC721.sol"; | |
| import "@openzeppelin/contracts@4.9.3/token/ERC721/extensions/ERC721URIStorage.sol"; | |
| import "@openzeppelin/contracts@4.9.3/token/ERC721/extensions/ERC721Burnable.sol"; | |
| import "@openzeppelin/contracts@4.9.3/access/Ownable.sol"; | |
| import "@openzeppelin/contracts@4.9.3/utils/Counters.sol"; | |
| import "@openzeppelin/contracts@4.9.3/token/ERC20/IERC20.sol"; | |
| contract SHARES is ERC721, ERC721URIStorage, ERC721Burnable, Ownable { | |
| using Counters for Counters.Counter; | |
| Counters.Counter private _tokenIdCounter; | |
| uint256 public villaCount; | |
| address public USDT_ADDRESS; | |
| struct Villa { | |
| uint256 id; | |
| string uid; | |
| string name; | |
| uint256 buyPrice; | |
| uint256 sellPrice; | |
| string uri; | |
| uint256 max_nft_count; | |
| uint256 minted_nft; | |
| } | |
| mapping(uint256 => Villa) public villa; | |
| constructor(address _usdt) ERC721("S.H.A.R.E.S", "SHR") { | |
| USDT_ADDRESS = _usdt; | |
| } | |
| function safeMint(address to, string memory uri) public onlyOwner { | |
| uint256 tokenId = _tokenIdCounter.current(); | |
| _tokenIdCounter.increment(); | |
| _safeMint(to, tokenId); | |
| _setTokenURI(tokenId, uri); | |
| } | |
| //create new villa with nft | |
| function createVilla( | |
| string memory uid, | |
| string memory name, | |
| string memory uri, | |
| uint256 buyPrice, | |
| uint256 sellPrice, | |
| uint256 max_nft_count) public onlyOwner { | |
| uint256 villaId = villaCount++; | |
| villa[villaId] = Villa(villaId, uid, name, buyPrice, sellPrice, uri, max_nft_count, 0); | |
| } | |
| function updateVillaBuyPrice(uint256 villaid, uint256 price) public onlyOwner { | |
| require(villaid < villaCount, "Villa ID does not exist"); | |
| require(price > 0, "Invalid Price"); | |
| villa[villaid].buyPrice = price; | |
| } | |
| function updateVillaSellPrice(uint256 villaid, uint256 price) public onlyOwner { | |
| require(villaid < villaCount, "Villa ID does not exist"); | |
| require(price > 0, "Invalid Price"); | |
| villa[villaid].sellPrice = price; | |
| } | |
| function buyShare(uint256 villaid, uint256 share_amount) public returns (uint256[] memory){ | |
| require(villaid < villaCount, "Villa ID does not exist"); | |
| require(villa[villaid].minted_nft + share_amount <= villa[villaid].max_nft_count, "Exceeds maximum NFT count for villa"); | |
| IERC20 usdt_token = IERC20(USDT_ADDRESS); | |
| uint256 buyPrice = villa[villaid].buyPrice; | |
| uint256 totalCost = buyPrice * share_amount; | |
| require(usdt_token.balanceOf(msg.sender) >= totalCost, "Insufficient USDT balance"); | |
| require(usdt_token.allowance(msg.sender, address(this)) >= totalCost, "Allowance not sufficient"); | |
| usdt_token.transferFrom(msg.sender, address(this), totalCost); | |
| uint256[] memory mintedTokenIds = new uint256[](share_amount); | |
| //mint nft | |
| for (uint256 i = 0; i < share_amount; i++) { | |
| villa[villaid].minted_nft++; | |
| uint256 tokenId = _tokenIdCounter.current(); | |
| _tokenIdCounter.increment(); | |
| _safeMint(msg.sender, tokenId); | |
| _setTokenURI(tokenId, villa[villaid].uri); | |
| mintedTokenIds[i] = tokenId; | |
| } | |
| return mintedTokenIds; | |
| } | |
| function sellShare(uint256 villaid, uint256[] memory tokenids) public returns (uint256[] memory) { | |
| require(villaid < villaCount, "Villa ID does not exist"); | |
| require(tokenids.length > 0, "Invalid Token Ids"); | |
| IERC20 usdt_token = IERC20(USDT_ADDRESS); | |
| uint256 sellPrice = villa[villaid].sellPrice * tokenids.length; | |
| usdt_token.approve(msg.sender, sellPrice); | |
| //check all token if approce | |
| for (uint256 i = 0; i < tokenids.length; i++) { | |
| require(getApproved(tokenids[i]) == address(this), "Token Id not approve"); | |
| } | |
| //send the usdt | |
| uint256[] memory sellTokenIds = new uint256[](tokenids.length); | |
| usdt_token.transfer(msg.sender, sellPrice); | |
| for (uint256 i = 0; i < tokenids.length; i++) { | |
| //transfer nft | |
| //todo save sell share | |
| villa[villaid].minted_nft--; | |
| transferFrom(msg.sender, address(this), tokenids[i]); | |
| } | |
| return sellTokenIds; | |
| } | |
| function usdtBalance() public view onlyOwner returns (uint256) { | |
| IERC20 usdt_token = IERC20(USDT_ADDRESS); | |
| return usdt_token.balanceOf(address(this)); | |
| } | |
| function withdraw() public onlyOwner { | |
| IERC20 usdt_token = IERC20(USDT_ADDRESS); | |
| uint256 balance = usdt_token.balanceOf(address(this)); | |
| require(usdt_token.balanceOf(address(this)) > 0, "not enough usdt"); | |
| usdt_token.transfer(msg.sender, balance); | |
| } | |
| // The following functions are overrides required by Solidity. | |
| function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { | |
| super._burn(tokenId); | |
| } | |
| function tokenURI(uint256 tokenId) | |
| public | |
| view | |
| override(ERC721, ERC721URIStorage) | |
| returns (string memory) | |
| { | |
| return super.tokenURI(tokenId); | |
| } | |
| function supportsInterface(bytes4 interfaceId) | |
| public | |
| view | |
| override(ERC721, ERC721URIStorage) | |
| returns (bool) | |
| { | |
| return super.supportsInterface(interfaceId); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment