Skip to content

Instantly share code, notes, and snippets.

@Jayke770
Created September 7, 2023 14:20
Show Gist options
  • Select an option

  • Save Jayke770/5984c75a75fdfee4a780b94c4fbe6e6a to your computer and use it in GitHub Desktop.

Select an option

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=
// 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