diff --git a/contracts/NFTexchange/Lib/State.sol b/contracts/NFTexchange/Lib/State.sol index f8ff854..a23e897 100644 --- a/contracts/NFTexchange/Lib/State.sol +++ b/contracts/NFTexchange/Lib/State.sol @@ -2,8 +2,6 @@ pragma solidity ^0.8.0; import "./Order.sol"; -import "../NFTexchangeCore.sol"; - library State { diff --git a/contracts/NFTexchange/Marketmanage.sol b/contracts/NFTexchange/Marketmanage.sol new file mode 100644 index 0000000..8f7cb89 --- /dev/null +++ b/contracts/NFTexchange/Marketmanage.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/access/Ownable.sol"; + +abstract contract marketmanage is Ownable { + + address owner; + address protcolfee; + + function + + +} diff --git a/contracts/NFTexchange/NFTexchange.sol b/contracts/NFTexchange/NFTexchange.sol index 277a3d4..0b4f514 100644 --- a/contracts/NFTexchange/NFTexchange.sol +++ b/contracts/NFTexchange/NFTexchange.sol @@ -5,6 +5,7 @@ import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; @@ -20,7 +21,7 @@ import "./Lib/interface/IOrder.sol"; import "../royalties/IERC2981Royalties.sol"; -contract NFTexchange is ReentrancyGuard, Validate { +contract NFTexchange is ReentrancyGuard, Validate, Initializable { using Counters for Counters.Counter; using SafeMath for uint; @@ -54,6 +55,9 @@ contract NFTexchange is ReentrancyGuard, Validate { State.stateItem state ); + function initialize() public initializer { + // we can set param for update + } function createMarketItem(Order.OrderItem memory _order) public { diff --git a/contracts/Tokens/LazyMint/TokenERC1155LazyMint.sol b/contracts/Tokens/LazyMint/TokenERC1155LazyMint.sol index 8b6bbfa..e8eb378 100644 --- a/contracts/Tokens/LazyMint/TokenERC1155LazyMint.sol +++ b/contracts/Tokens/LazyMint/TokenERC1155LazyMint.sol @@ -3,13 +3,15 @@ pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; +import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; -import "../../royalties/impl/RoyaltiesV2impl.sol"; +import "../../royalties/impl/RoyaltiesV2Impl.sol"; +import "./signtureEIP712/signtureERC1155.sol"; import "../../royalties/LibRoyality.sol"; import "../../royalties/LibRoyaltiesV2.sol"; -contract TokenERC1155LazyMint is ERC1155, ERC1155Burnable, Ownable, RoyaltiesV2Impl { +contract TokenERC1155LazyMint is ERC1155, ERC1155Burnable, Ownable, AccessControl, RoyaltiesV2Impl, signtureERC1155 { bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a; address public contractAddress; @@ -17,18 +19,12 @@ contract TokenERC1155LazyMint is ERC1155, ERC1155Burnable, Ownable, RoyaltiesV2 string contracturi; mapping(uint256 => uint256) public tokenIds; mapping (uint256 => string) public _tokenURIs; + bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); string private _baseURI; - struct NFTVoucher { - uint256 tokenId; - uint256 minPrice; - uint256 supply; - address account; - string uri; - } - - constructor(string memory _uri, address contractAddr) ERC1155(_uri) { + constructor(string memory _uri, address minter, address contractAddr) ERC1155(_uri) { + _setupRole(MINTER_ROLE, minter); TokenURI = _uri; contractAddress = contractAddr; contracturi = _uri; @@ -40,12 +36,20 @@ contract TokenERC1155LazyMint is ERC1155, ERC1155Burnable, Ownable, RoyaltiesV2 function Lazymint(NFTVoucher calldata voucher, address redeemer, bytes memory signature ,bytes memory data) public - onlyOwner + payable { + address signer = _verify(voucher, signature); + + require(hasRole(MINTER_ROLE, signer), "Invalid signature - unknown signer"); + require(msg.value >= voucher.minPrice, "Insufficient funds to redeem"); + _mint(voucher.account, voucher.tokenId, voucher.supply, data); tokenIds[voucher.tokenId] = voucher.tokenId; setTokenURI(voucher.tokenId, voucher.uri); + safeTransferFrom(voucher.account, redeemer, voucher.tokenId, voucher.supply, data); setApprovalForAll(contractAddress, true); + address payable receiver = payable(signer); + receiver.transfer(msg.value); } function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) @@ -101,7 +105,7 @@ contract TokenERC1155LazyMint is ERC1155, ERC1155Burnable, Ownable, RoyaltiesV2 public view virtual - override + override(AccessControl,ERC1155) returns (bool) { if (interfaceId == LibRoyaltiesV2._INTERFACE_ID_ROYALTIES) { diff --git a/contracts/Tokens/LazyMint/TokenERC721LazyMint.sol b/contracts/Tokens/LazyMint/TokenERC721LazyMint.sol index 37e726b..d4602fb 100644 --- a/contracts/Tokens/LazyMint/TokenERC721LazyMint.sol +++ b/contracts/Tokens/LazyMint/TokenERC721LazyMint.sol @@ -9,11 +9,12 @@ import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol"; -import "../../royalties/impl/RoyaltiesV2impl.sol"; +import "./signtureEIP712/signtureERC721.sol"; +import "../../royalties/impl/RoyaltiesV2Impl.sol"; import "../../royalties/LibRoyality.sol"; import "../../royalties/LibRoyaltiesV2.sol"; -contract TokenERC721LazyMint is ERC721URIStorage, ERC721Burnable, RoyaltiesV2Impl, Ownable, EIP712, AccessControl { +contract TokenERC721LazyMint is ERC721URIStorage, ERC721Burnable, RoyaltiesV2Impl, Ownable, signtureERC721, AccessControl { using ECDSA for bytes32; using Counters for Counters.Counter; Counters.Counter private _tokenIdCounter; @@ -28,11 +29,6 @@ contract TokenERC721LazyMint is ERC721URIStorage, ERC721Burnable, RoyaltiesV2Imp mapping(uint256 => uint256) public getTokenIDs; mapping(address => uint256) public tokenIds; - struct NFTVoucher { - uint256 tokenId; - uint256 minPrice; - string uri; - } modifier isOwnerTokenId(uint256 _tokenId) { require(ownerOf(_tokenId) == address(msg.sender) , "you should be owner this token id"); @@ -41,28 +37,12 @@ contract TokenERC721LazyMint is ERC721URIStorage, ERC721Burnable, RoyaltiesV2Imp constructor (string memory _name, string memory _symbol, address minter, address contractAddr, string memory _contracturi) ERC721(_name, _symbol) - EIP712("LazyNFT-Voucher", "1") { _setupRole(MINTER_ROLE, minter); contractAddress = contractAddr; contracturi = _contracturi; } - function _hash(NFTVoucher calldata voucher) internal view returns (bytes32) { - return _hashTypedDataV4(keccak256(abi.encode( - keccak256("NFTVoucher(uint256 tokenId,uint256 minPrice,string uri)"), - voucher.tokenId, - voucher.minPrice, - keccak256(bytes(voucher.uri)) - ))); - } - - - function _verify(NFTVoucher calldata voucher, bytes memory signature) internal view returns (address) { - bytes32 digest = _hash(voucher); - return digest.toEthSignedMessageHash().recover(signature); - } - function contractURI() public view returns (string memory) { return contracturi; } @@ -75,7 +55,7 @@ contract TokenERC721LazyMint is ERC721URIStorage, ERC721Burnable, RoyaltiesV2Imp super._burn(tokenId); } - function lazyMint(address redeemer, NFTVoucher calldata voucher, bytes memory signature) public payable { + function lazyMint(address redeemer, signtureEIP721.NFTVoucher calldata voucher, bytes memory signature) public payable { address signer = _verify(voucher, signature); require(hasRole(MINTER_ROLE, signer), "Invalid signature - unknown signer"); diff --git a/contracts/Tokens/LazyMint/signtureEIP712/signtureERC1155.sol b/contracts/Tokens/LazyMint/signtureEIP712/signtureERC1155.sol new file mode 100644 index 0000000..d49c313 --- /dev/null +++ b/contracts/Tokens/LazyMint/signtureEIP712/signtureERC1155.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + + +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol"; + +abstract contract signtureERC1155 is EIP712 { + using ECDSA for bytes32; + + + struct NFTVoucher { + uint256 tokenId; + uint256 minPrice; + uint256 supply; + address account; + string uri; + } + + constructor () + EIP712("LazyNFT-Voucher", "1") + { + + } + + function _hash(NFTVoucher calldata voucher) internal view returns (bytes32) { + return _hashTypedDataV4(keccak256(abi.encode( + keccak256("NFTVoucher(uint256 tokenId,uint256 minPrice,uint256 supply,address account,string uri)"), + voucher.tokenId, + voucher.minPrice, + voucher.supply, + voucher.account, + keccak256(bytes(voucher.uri)) + ))); + } + + + function _verify(NFTVoucher calldata voucher, bytes memory signature) internal view returns (address) { + bytes32 digest = _hash(voucher); + return digest.toEthSignedMessageHash().recover(signature); + } + +} diff --git a/contracts/Tokens/LazyMint/signtureEIP712/signtureERC721.sol b/contracts/Tokens/LazyMint/signtureEIP712/signtureERC721.sol new file mode 100644 index 0000000..e1b39e7 --- /dev/null +++ b/contracts/Tokens/LazyMint/signtureEIP712/signtureERC721.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + + +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol"; + +abstract contract signtureERC721 is EIP712 { + using ECDSA for bytes32; + + + struct NFTVoucher { + uint256 tokenId; + uint256 minPrice; + string uri; + } + + constructor () + EIP712("LazyNFT-Voucher", "1") + { + + } + + function _hash(NFTVoucher calldata voucher) internal view returns (bytes32) { + return _hashTypedDataV4(keccak256(abi.encode( + keccak256("NFTVoucher(uint256 tokenId,uint256 minPrice,string uri)"), + voucher.tokenId, + voucher.minPrice, + keccak256(bytes(voucher.uri)) + ))); + } + + + function _verify(NFTVoucher calldata voucher, bytes memory signature) internal view returns (address) { + bytes32 digest = _hash(voucher); + return digest.toEthSignedMessageHash().recover(signature); + } + +} diff --git a/migrations/2_deploy_NFTexchange.js b/migrations/2_deploy_NFTexchange.js new file mode 100644 index 0000000..2908ac4 --- /dev/null +++ b/migrations/2_deploy_NFTexchange.js @@ -0,0 +1,8 @@ +const { deployProxy } = require('@openzeppelin/truffle-upgrades'); + +const NFTexchange = artifacts.require('NFTexchange'); + +module.exports = async function (deployer) { + const instance = await deployProxy(NFTexchange, { deployer }); + console.log('Deployed', instance.address); +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d73d295..7022d1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "": { "dependencies": { "@openzeppelin/contracts": "^4.6.0", + "@openzeppelin/contracts-upgradeable": "^4.6.0", "dotenv": "^16.0.0" }, "devDependencies": { @@ -1265,6 +1266,11 @@ "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.6.0.tgz", "integrity": "sha512-8vi4d50NNya/bQqCmaVzvHNmwHvS0OBKb7HNtuNwEE3scXWrP31fKQoGxNMT+KbzmrNZzatE3QK5p2gFONI/hg==" }, + "node_modules/@openzeppelin/contracts-upgradeable": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.6.0.tgz", + "integrity": "sha512-5OnVuO4HlkjSCJO165a4i2Pu1zQGzMs//o54LPrwUgxvEO2P3ax1QuaSI0cEHHTveA77guS0PnNugpR2JMsPfA==" + }, "node_modules/@openzeppelin/truffle-upgrades": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/@openzeppelin/truffle-upgrades/-/truffle-upgrades-1.15.0.tgz", @@ -16641,6 +16647,11 @@ "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.6.0.tgz", "integrity": "sha512-8vi4d50NNya/bQqCmaVzvHNmwHvS0OBKb7HNtuNwEE3scXWrP31fKQoGxNMT+KbzmrNZzatE3QK5p2gFONI/hg==" }, + "@openzeppelin/contracts-upgradeable": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.6.0.tgz", + "integrity": "sha512-5OnVuO4HlkjSCJO165a4i2Pu1zQGzMs//o54LPrwUgxvEO2P3ax1QuaSI0cEHHTveA77guS0PnNugpR2JMsPfA==" + }, "@openzeppelin/truffle-upgrades": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/@openzeppelin/truffle-upgrades/-/truffle-upgrades-1.15.0.tgz", diff --git a/package.json b/package.json index 90e9fce..e63e3a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "dependencies": { "@openzeppelin/contracts": "^4.6.0", + "@openzeppelin/contracts-upgradeable": "^4.6.0", "dotenv": "^16.0.0" }, "devDependencies": {