Skip to content

Instantly share code, notes, and snippets.

@savchart
Created September 18, 2022 01:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save savchart/fa1b5aa9cc295e5c41c85eff2c49d555 to your computer and use it in GitHub Desktop.
Save savchart/fa1b5aa9cc295e5c41c85eff2c49d555 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./ProjectNFT.sol";
contract ProjectManager {
uint256 constant public fee = 10 ** 17;
mapping(address => bool) public supportedCurrencies;
address payable public owner;
event ProjectCreated(address projectAddress, string projectURI);
event GetReturns(address projectAddress, uint16 tokenId, string returnsID);
constructor(address[] memory _supportedCurrencies) {
owner = payable(msg.sender);
for (uint i=0; i < _supportedCurrencies.length; i++) {
supportedCurrencies[_supportedCurrencies[i]] = true;
}
supportedCurrencies[address(0)] = true;
}
function withdraw() public {
require(msg.sender == owner, "only owner could withdraw");
owner.transfer(address(this).balance);
}
function createProject(string calldata projectName, string calldata projectSymbol, string calldata projectURI, uint16 ticketsTotal, address currency, uint256 price, uint256 interest) public payable {
require(msg.value >= fee, "too small fee");
require(supportedCurrencies[currency], "not supported currency");
ProjectNFT newProject = new ProjectNFT(msg.sender, projectName, projectSymbol, projectURI, ticketsTotal, currency, price, interest);
emit ProjectCreated(address(newProject), projectURI);
}
function attendProject(address projectAddress) public payable returns (uint16) {
ProjectNFT projectNftContract = ProjectNFT(projectAddress);
if (projectNftContract.currency() == address(0)) {
require(msg.value >= projectNftContract.price(), "too small amount");
payable(projectNftContract.projectOwner()).transfer(msg.value);
} else {
IERC20 token = IERC20(projectNftContract.currency());
token.transferFrom(msg.sender, projectNftContract.projectOwner(), projectNftContract.price());
}
return projectNftContract.mintToken(msg.sender);
}
function claimReturns(address projectAddress, uint16 tokenId, string memory returnsID) public {
ProjectNFT projectNftContract = ProjectNFT(projectAddress);
projectNftContract.burnToken(msg.sender, tokenId);
emit GetReturns(projectAddress, tokenId, returnsID);
}
}
// SPDX-License-Identifier: MTI
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract ProjectNFT is ERC721URIStorage, Ownable {
address public projectOwner;
uint16 public mintedCount;
uint16 public maxTokens;
string public commonTokenURI;
address public currency;
uint256 public price;
uint256 public interest;
constructor(address _projectOwner, string memory tokenName, string memory tokenSymbol, string memory _tokenURI, uint16 _maxTokens, address _currency, uint256 _price, uint256 _interest) ERC721(tokenName, tokenSymbol) {
projectOwner = _projectOwner;
commonTokenURI = _tokenURI;
maxTokens = _maxTokens;
currency = _currency;
price = _price;
interest = _interest;
}
function mintToken(address tokenOwner) public onlyOwner returns (uint16) {
require(mintedCount < maxTokens, "all tickets sold out");
mintedCount += 1;
uint16 newItemId = mintedCount;
_safeMint(tokenOwner, newItemId);
_setTokenURI(newItemId, commonTokenURI);
return newItemId;
}
function burnToken(address tokenOwner, uint16 tokenId) public onlyOwner payable {
require(_isApprovedOrOwner(tokenOwner, tokenId), "not an owner to burn the token");
payable(tokenOwner).transfer(price+interest);
_burn(tokenId);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment