123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- // SPDX-License-Identifier: MIT
- pragma solidity ^0.8.0; // 몇으로 할까
- import "../contracts/utils/cryptography/ECDSA.sol";
- import "../contracts/utils/cryptography/draft-EIP712.sol";
- import "../contracts/utils/math/SafeMath.sol";
- interface IMetaRareERC721Collection {
- function mint(address, uint256) external;
- function hasRole(bytes32, address) external view returns (bool);
- function ownerOf(uint256 tokenId) external view returns (address);
- function transferFrom(address from, address to, uint256 tokenId) external;
- function transferOnlyOperator(address, address, uint256) external;
- }
- interface IMetaRareERC1155Collection {
- function owner() external view returns (address);
- function exists(uint256) external view returns (bool);
- function createByOperator(address, uint256, uint256, string memory, bytes memory) external returns (uint256);
- function safeTransferFrom(address, address, uint256, uint256, bytes memory) external;
- function balanceOf(address, uint256) external view returns (uint256);
- function transferOnlyOperator(address, address, uint256, uint256) external;
- }
- interface IERC20 {
- function transfer(address to, uint256 amount) external returns (bool);
- function transferFrom(address from, address to, uint256 value) external returns (bool);
- function approve(address spender, uint256 value) external returns (bool);
- function balanceOf(address owner) external view returns (uint256);
- }
- contract MetaRareOperator is EIP712 {
- using SafeMath for uint256;
- mapping (uint256 => address) public creators;
- mapping (address => mapping(uint256 => address)) public creatorsWithinCollection;
- mapping (address => mapping(uint256 => uint256)) public creationTaxRate;
- struct NFTVoucher {
- address signer;
- address tokenAddress;
- uint256 tokenType;
- uint256 tokenId;
- address assetAddress;
- uint256 price;
- uint256 balance;
- uint256 totalBalance;
- uint256 creationTax;
- uint256 treasuryTax;
- address treasuryAddress;
- string uri;
- }
- constructor() EIP712("METARARE","1"){
- }
- bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
- bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
- address payable private _treasury;
- function recoverAddress(bytes32 msgHash, uint8 v, bytes32 r, bytes32 s) public pure returns(address) {
- return ecrecover(msgHash, v, r, s);
- }
-
- function excuteMintingOrderWithERC721Collection(NFTVoucher calldata voucher, bytes32 hash, uint8 v, bytes32 r, bytes32 s) public payable {
- address signer = recoverAddress(hash, v,r,s);
- require(signer == voucher.signer, "Invalid signature");
- creators[voucher.tokenId] = signer;
- creatorsWithinCollection[voucher.tokenAddress][voucher.tokenId] = creators[voucher.tokenId];
- creationTaxRate[voucher.tokenAddress][voucher.tokenId] = voucher.creationTax;
- _treasury = payable(voucher.treasuryAddress);
- address ERC721TokenAddress = voucher.tokenAddress;
- IMetaRareERC721Collection _ERC721Collection = IMetaRareERC721Collection(ERC721TokenAddress);
- require(_ERC721Collection.hasRole(MINTER_ROLE, signer), "Signature invalid or unauthorized");
- if (voucher.assetAddress == address(0)) {
- require(msg.value >= voucher.price, "No money");
-
- address payable targetAddress;
- targetAddress = payable(signer);
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_seller = voucher.price.sub(value_treasury);
- _treasury.transfer(value_treasury);
- targetAddress.transfer(value_seller);
- }
- else {
- IERC20 tokenContract = IERC20(voucher.assetAddress);
- require(tokenContract.balanceOf(msg.sender) >= voucher.price, "No money");
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_seller = voucher.price.sub(value_treasury);
- tokenContract.transferFrom(msg.sender, _treasury, value_treasury);
- tokenContract.transferFrom(msg.sender, signer, value_seller);
- }
- _ERC721Collection.mint(msg.sender, voucher.tokenId);
- }
- function excuteMintingOrderWithERC721MetaRareCollection(NFTVoucher calldata voucher, bytes32 hash, uint8 v, bytes32 r, bytes32 s) public payable {
- address signer = recoverAddress(hash, v,r,s);
- require(signer == voucher.signer, "Invalid signature");
- creators[voucher.tokenId] = signer;
- creatorsWithinCollection[voucher.tokenAddress][voucher.tokenId] = creators[voucher.tokenId];
- creationTaxRate[voucher.tokenAddress][voucher.tokenId] = voucher.creationTax;
- _treasury = payable(voucher.treasuryAddress);
- address ERC721TokenAddress = voucher.tokenAddress;
- IMetaRareERC721Collection _ERC721Collection = IMetaRareERC721Collection(ERC721TokenAddress);
- if (voucher.assetAddress == address(0)) {
- require(msg.value >= voucher.price, "No money");
-
- address payable targetAddress;
- targetAddress = payable(signer);
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_seller = voucher.price.sub(value_treasury);
- _treasury.transfer(value_treasury);
- targetAddress.transfer(value_seller);
- }
- else {
- IERC20 tokenContract = IERC20(voucher.assetAddress);
- require(tokenContract.balanceOf(msg.sender) >= voucher.price, "No money");
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_seller = voucher.price.sub(value_treasury);
- tokenContract.transferFrom(msg.sender, _treasury, value_treasury);
- tokenContract.transferFrom(msg.sender, signer, value_seller);
- }
- _ERC721Collection.mint(msg.sender, voucher.tokenId);
- }
- function excuteTransferOrderWithERC721Collection(NFTVoucher calldata voucher, bytes32 hash, uint8 v, bytes32 r, bytes32 s) public payable {
- address signer = recoverAddress(hash, v,r,s);
- require(signer == voucher.signer, "Invalid signature");
- _treasury = payable(voucher.treasuryAddress);
- address ERC721TokenAddress = voucher.tokenAddress;
- IMetaRareERC721Collection _ERC721Collection = IMetaRareERC721Collection(ERC721TokenAddress);
- require(_ERC721Collection.ownerOf(voucher.tokenId) == signer, "Signature invalid or unauthorized");
- if (voucher.assetAddress == address(0)) {
- require(msg.value >= voucher.price, "No money");
-
- address payable targetAddress;
- targetAddress = payable(signer);
- address payable creatorAddress;
- creatorAddress = payable(creatorsWithinCollection[voucher.tokenAddress][voucher.tokenId]);
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_creator = voucher.price.mul(voucher.creationTax).div(10000);
- uint256 value_seller = voucher.price;
- value_seller = value_seller.sub(value_treasury).sub(value_creator);
- _treasury.transfer(value_treasury);
- creatorAddress.transfer(value_creator);
- targetAddress.transfer(value_seller);
- }
- else {
- IERC20 tokenContract = IERC20(voucher.assetAddress);
- require(tokenContract.balanceOf(msg.sender) >= voucher.price, "No money");
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_creator = voucher.price.mul(voucher.creationTax).div(10000);
- uint256 value_seller = voucher.price.sub(value_treasury).sub(value_creator);
- tokenContract.transferFrom(msg.sender, _treasury, value_treasury);
- address _creator = creatorsWithinCollection[voucher.tokenAddress][voucher.tokenId];
- tokenContract.transferFrom(msg.sender, _creator, value_creator);
- tokenContract.transferFrom(msg.sender, signer, value_seller);
- }
- _ERC721Collection.transferOnlyOperator(signer, msg.sender, voucher.tokenId);
- }
- function excuteMintingOrderWithERC1155Collection(NFTVoucher calldata voucher, bytes32 hash, uint8 v, bytes32 r, bytes32 s) public payable {
- address signer = recoverAddress(hash, v,r,s);
- require(signer == voucher.signer, "Invalid signature");
- creators[voucher.tokenId] = signer;
- creatorsWithinCollection[voucher.tokenAddress][voucher.tokenId] = creators[voucher.tokenId];
- creationTaxRate[voucher.tokenAddress][voucher.tokenId] = voucher.creationTax;
- _treasury = payable(voucher.treasuryAddress);
- address ERC1155TokenAddress = voucher.tokenAddress;
- IMetaRareERC1155Collection _ERC1155Collection = IMetaRareERC1155Collection(ERC1155TokenAddress);
- require(_ERC1155Collection.owner() == signer, "Signature invalid or unauthorized");
- if (voucher.assetAddress == address(0)) {
- require(msg.value >= voucher.price, "No money");
-
- address payable targetAddress;
- targetAddress = payable(signer);
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_seller = voucher.price.sub(value_treasury);
- _treasury.transfer(value_treasury);
- targetAddress.transfer(value_seller);
- }
- else {
- IERC20 tokenContract = IERC20(voucher.assetAddress);
- require(tokenContract.balanceOf(msg.sender) >= voucher.price, "No money");
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_seller = voucher.price.sub(value_treasury);
- tokenContract.transferFrom(msg.sender, _treasury, value_treasury);
- tokenContract.transferFrom(msg.sender, signer, value_seller);
- }
- if(!_ERC1155Collection.exists(voucher.tokenId)) {
- _ERC1155Collection.createByOperator(signer, voucher.tokenId, voucher.totalBalance, voucher.uri, "");
- _ERC1155Collection.safeTransferFrom(signer, msg.sender, voucher.tokenId, voucher.balance, "");
- }
- else {
- _ERC1155Collection.safeTransferFrom(signer, msg.sender, voucher.tokenId, voucher.balance, "");
- }
- }
- function excuteMintingOrderWithERC1155MetaRareCollection(NFTVoucher calldata voucher, bytes32 hash, uint8 v, bytes32 r, bytes32 s) public payable {
- address signer = recoverAddress(hash, v,r,s);
- require(signer == voucher.signer, "Invalid signature");
- creators[voucher.tokenId] = signer;
- creatorsWithinCollection[voucher.tokenAddress][voucher.tokenId] = creators[voucher.tokenId];
- creationTaxRate[voucher.tokenAddress][voucher.tokenId] = voucher.creationTax;
- _treasury = payable(voucher.treasuryAddress);
- address ERC1155TokenAddress = voucher.tokenAddress;
- IMetaRareERC1155Collection _ERC1155Collection = IMetaRareERC1155Collection(ERC1155TokenAddress);
- if (voucher.assetAddress == address(0)) {
- require(msg.value >= voucher.price, "No money");
-
- address payable targetAddress;
- targetAddress = payable(signer);
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_seller = voucher.price.sub(value_treasury);
- _treasury.transfer(value_treasury);
- targetAddress.transfer(value_seller);
- }
- else {
- IERC20 tokenContract = IERC20(voucher.assetAddress);
- require(tokenContract.balanceOf(msg.sender) >= voucher.price, "No money");
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_seller = voucher.price.sub(value_treasury);
- tokenContract.transferFrom(msg.sender, _treasury, value_treasury);
- tokenContract.transferFrom(msg.sender, signer, value_seller);
- }
- if(!_ERC1155Collection.exists(voucher.tokenId)) {
- _ERC1155Collection.createByOperator(signer, voucher.tokenId, voucher.totalBalance, voucher.uri, "");
- _ERC1155Collection.transferOnlyOperator(signer, msg.sender, voucher.tokenId, voucher.balance);
- }
- else {
- _ERC1155Collection.transferOnlyOperator(signer, msg.sender, voucher.tokenId, voucher.balance);
- }
- }
- function excuteTransferOrderWithERC1155Collection(NFTVoucher calldata voucher, bytes32 hash, uint8 v, bytes32 r, bytes32 s) public payable {
- address signer = recoverAddress(hash, v,r,s);
- require(signer == voucher.signer, "Invalid signature");
- _treasury = payable(voucher.treasuryAddress);
- address ERC1155TokenAddress = voucher.tokenAddress;
- IMetaRareERC1155Collection _ERC1155Collection = IMetaRareERC1155Collection(ERC1155TokenAddress);
- require(_ERC1155Collection.balanceOf(signer, voucher.tokenId) >= voucher.balance, "Signature invalid or unauthorized");
- if (voucher.assetAddress == address(0)) {
- require(msg.value >= voucher.price, "No money");
-
- address payable targetAddress;
- targetAddress = payable(signer);
- address payable creatorAddress;
- creatorAddress = payable(creatorsWithinCollection[voucher.tokenAddress][voucher.tokenId]);
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_creator = voucher.price;
- value_creator = value_creator.mul(voucher.creationTax).div(10000);
- uint256 value_seller = voucher.price;
- value_seller = value_seller.sub(value_treasury).sub(value_creator);
- _treasury.transfer(value_treasury);
- creatorAddress.transfer(value_creator);
- targetAddress.transfer(value_seller);
- }
- else {
- IERC20 tokenContract = IERC20(voucher.assetAddress);
- require(tokenContract.balanceOf(msg.sender) >= voucher.price, "No money");
- uint256 value_treasury = voucher.price.mul(voucher.treasuryTax).div(10000);
- uint256 value_creator = voucher.price.mul(voucher.creationTax).div(10000);
- uint256 value_seller = voucher.price.sub(value_treasury).sub(value_creator);
- address _creator = creatorsWithinCollection[voucher.tokenAddress][voucher.tokenId];
- tokenContract.transferFrom(msg.sender, _treasury, value_treasury);
- tokenContract.transferFrom(msg.sender, _creator, value_creator);
- tokenContract.transferFrom(msg.sender, signer, value_seller);
- }
- _ERC1155Collection.transferOnlyOperator(signer, msg.sender, voucher.tokenId, voucher.balance);
- }
- }
|