diff --git a/contracts/core/HasSignature.sol b/contracts/core/HasSignature.sol index e623107..9ecaacb 100644 --- a/contracts/core/HasSignature.sol +++ b/contracts/core/HasSignature.sol @@ -4,93 +4,8 @@ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract HasSignature is Ownable { - bytes32 private immutable _CACHED_DOMAIN_SEPARATOR; - uint256 private immutable _CACHED_CHAIN_ID; - address private immutable _CACHED_THIS; - - bytes32 private immutable _HASHED_NAME; - bytes32 private immutable _HASHED_VERSION; - bytes32 private immutable _TYPE_HASH; mapping(bytes => bool) private _usedSignatures; - constructor(string memory name, string memory version) { - bytes32 hashedName = keccak256(bytes(name)); - bytes32 hashedVersion = keccak256(bytes(version)); - bytes32 typeHash = keccak256( - "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" - ); - _HASHED_NAME = hashedName; - _HASHED_VERSION = hashedVersion; - _CACHED_CHAIN_ID = block.chainid; - _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator( - typeHash, - hashedName, - hashedVersion - ); - _CACHED_THIS = address(this); - _TYPE_HASH = typeHash; - } - - function _buildDomainSeparator( - bytes32 typeHash, - bytes32 nameHash, - bytes32 versionHash - ) private view returns (bytes32) { - return - keccak256( - abi.encode( - typeHash, - nameHash, - versionHash, - block.chainid, - address(this) - ) - ); - } - - /** - * @dev Returns the domain separator for the current chain. - */ - function _domainSeparatorV4() internal view returns (bytes32) { - if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) { - return _CACHED_DOMAIN_SEPARATOR; - } else { - return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); - } - } - - /** - * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this - * function returns the hash of the fully encoded EIP712 message for this domain. - * - * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: - * - * ```solidity - * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( - * keccak256("Mail(address to,string contents)"), - * mailTo, - * keccak256(bytes(mailContents)) - * ))); - * address signer = ECDSA.recover(digest, signature); - * ``` - */ - function _hashTypedDataV4( - bytes32 structHash - ) internal view virtual returns (bytes32) { - return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); - } - - function checkSigner712( - address signer, - bytes32 structHash, - bytes memory signature - ) public view { - require(signer != address(0), "[BE] invalid signer"); - bytes32 digest = _hashTypedDataV4(structHash); - address recovered = ECDSA.recover(digest, signature); - require(recovered == signer, "[BE] invalid signature"); - } - function checkSigner( address signer, bytes32 hash, diff --git a/contracts/core/HasSignature712.sol b/contracts/core/HasSignature712.sol new file mode 100644 index 0000000..3b66d4d --- /dev/null +++ b/contracts/core/HasSignature712.sol @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract HasSignature is Ownable { + bytes32 private immutable _CACHED_DOMAIN_SEPARATOR; + uint256 private immutable _CACHED_CHAIN_ID; + address private immutable _CACHED_THIS; + + bytes32 private immutable _HASHED_NAME; + bytes32 private immutable _HASHED_VERSION; + bytes32 private immutable _TYPE_HASH; + mapping(bytes => bool) private _usedSignatures; + + constructor(string memory name, string memory version) { + bytes32 hashedName = keccak256(bytes(name)); + bytes32 hashedVersion = keccak256(bytes(version)); + bytes32 typeHash = keccak256( + "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" + ); + _HASHED_NAME = hashedName; + _HASHED_VERSION = hashedVersion; + _CACHED_CHAIN_ID = block.chainid; + _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator( + typeHash, + hashedName, + hashedVersion + ); + _CACHED_THIS = address(this); + _TYPE_HASH = typeHash; + } + + function _buildDomainSeparator( + bytes32 typeHash, + bytes32 nameHash, + bytes32 versionHash + ) private view returns (bytes32) { + return + keccak256( + abi.encode( + typeHash, + nameHash, + versionHash, + block.chainid, + address(this) + ) + ); + } + + /** + * @dev Returns the domain separator for the current chain. + */ + function _domainSeparatorV4() internal view returns (bytes32) { + if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) { + return _CACHED_DOMAIN_SEPARATOR; + } else { + return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); + } + } + + /** + * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this + * function returns the hash of the fully encoded EIP712 message for this domain. + * + * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: + * + * ```solidity + * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( + * keccak256("Mail(address to,string contents)"), + * mailTo, + * keccak256(bytes(mailContents)) + * ))); + * address signer = ECDSA.recover(digest, signature); + * ``` + */ + function _hashTypedDataV4( + bytes32 structHash + ) internal view virtual returns (bytes32) { + return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); + } + + function checkSigner712( + address signer, + bytes32 structHash, + bytes memory signature + ) public view { + require(signer != address(0), "[BE] invalid signer"); + bytes32 digest = _hashTypedDataV4(structHash); + address recovered = ECDSA.recover(digest, signature); + require(recovered == signer, "[BE] invalid signature"); + } + + modifier signatureValid(bytes calldata signature) { + require( + !_usedSignatures[signature], + "[BE] signature used. please send another transaction with new signature" + ); + _; + } + + function _useSignature(bytes calldata signature) internal { + if (!_usedSignatures[signature]) { + _usedSignatures[signature] = true; + } + } +} diff --git a/contracts/logic/UserMinterFactory.sol b/contracts/logic/UserMinterFactory.sol index efb4d86..588f0c8 100644 --- a/contracts/logic/UserMinterFactory.sol +++ b/contracts/logic/UserMinterFactory.sol @@ -18,8 +18,6 @@ contract UserMinterFactory is Ownable, TimeChecker, HasSignature { uint256[] ids ); - constructor() HasSignature("UserMinterFactory", "1") {} - /** * @dev mint nft by user */ diff --git a/contracts/market/BENftMall.sol b/contracts/market/BENftMall.sol index 55bba58..e75dc56 100644 --- a/contracts/market/BENftMall.sol +++ b/contracts/market/BENftMall.sol @@ -15,8 +15,6 @@ contract BENftMall is MallBase, ReentrancyGuard, HasSignature, TimeChecker { using SafeERC20 for IERC20; using UInt for uint256; - constructor() HasSignature("NftMall", "1") {} - mapping(address => bool) public erc721Supported; mapping(address => bool) public erc1155Supported; diff --git a/contracts/market/BENftMarket.sol b/contracts/market/BENftMarket.sol index 2d28b4b..daeee10 100644 --- a/contracts/market/BENftMarket.sol +++ b/contracts/market/BENftMarket.sol @@ -286,7 +286,7 @@ contract BENftMarket is Ownable, ReentrancyGuard, ERC1155Holder, ERC721Holder { */ function removeERC721Support(address nftToken) external onlyOwner { erc721Supported[nftToken] = false; - erc1155SupportedHistory[nftToken] = true; + erc721SupportedHistory[nftToken] = true; emit RemoveNFTSuppout(nftToken); } diff --git a/contracts/market/GameItemMall.sol b/contracts/market/GameItemMall.sol index 4ad1304..1d1de05 100644 --- a/contracts/market/GameItemMall.sol +++ b/contracts/market/GameItemMall.sol @@ -18,8 +18,6 @@ contract GameItemMall is MallBase, ReentrancyGuard, HasSignature, TimeChecker { mapping(uint256 => address) public orderIdUsed; - constructor() HasSignature("GameItemMarket", "1") {} - event ItemSoldOut( address indexed buyer, uint256 indexed orderId, diff --git a/contracts/market/GameItemMarket.sol b/contracts/market/GameItemMarket.sol index d7d2d1d..a3dd471 100644 --- a/contracts/market/GameItemMarket.sol +++ b/contracts/market/GameItemMarket.sol @@ -28,8 +28,6 @@ contract GameItemMarket is // max transaction fee is: 10% uint256 public constant MAX_TRANSACTION_FEE = (10 * ROUND) / 100; - constructor() HasSignature("GameItemMarket", "1") {} - event ItemSoldOut( address indexed buyer, address indexed seller, diff --git a/contracts/market/MarketPlace.sol b/contracts/market/MarketPlace.sol index e8fe4b6..99cc48a 100644 --- a/contracts/market/MarketPlace.sol +++ b/contracts/market/MarketPlace.sol @@ -38,8 +38,6 @@ contract MarketPlace is Ownable, HasSignature { uint256 fee ); - constructor() HasSignature("MarketPlace", "1") {} - function setFeeToAddress(address _feeToAddress) external onlyOwner { require( _feeToAddress != address(0), @@ -57,10 +55,9 @@ contract MarketPlace is Ownable, HasSignature { transactionFee = _transactionFee; } - function setPaymentTokens(address[] calldata _paymentTokens) - external - onlyOwner - { + function setPaymentTokens( + address[] calldata _paymentTokens + ) external onlyOwner { for (uint256 i = 0; i < _paymentTokens.length; i++) { if (paymentTokens[_paymentTokens[i]]) { continue; @@ -70,10 +67,9 @@ contract MarketPlace is Ownable, HasSignature { } } - function removePaymentTokens(address[] calldata _removedPaymentTokens) - external - onlyOwner - { + function removePaymentTokens( + address[] calldata _removedPaymentTokens + ) external onlyOwner { for (uint256 i = 0; i < _removedPaymentTokens.length; i++) { paymentTokens[_removedPaymentTokens[i]] = false; } @@ -165,9 +161,10 @@ contract MarketPlace is Ownable, HasSignature { /** * @dev Function to emit transaction matched event */ - function emitEvent(address[3] calldata addresses, uint256[3] calldata values) - internal - { + function emitEvent( + address[3] calldata addresses, + uint256[3] calldata values + ) internal { emit MatchTransaction( values[0], addresses[1], diff --git a/contracts/tokens/erc20/FT.sol b/contracts/tokens/erc20/FT.sol index 9417948..5db7a73 100644 --- a/contracts/tokens/erc20/FT.sol +++ b/contracts/tokens/erc20/FT.sol @@ -2,11 +2,9 @@ pragma solidity 0.8.10; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; -import "@openzeppelin/contracts/security/Pausable.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; -contract FT is ERC20, ERC20Burnable, Pausable, AccessControl { - bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); +contract FT is ERC20, ERC20Burnable, AccessControl { bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); uint256 public immutable supplyLimit; @@ -16,21 +14,10 @@ contract FT is ERC20, ERC20Burnable, Pausable, AccessControl { uint256 _supplyLimt ) ERC20(name_, symbol_) { _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); - _setupRole(PAUSER_ROLE, msg.sender); _setupRole(MINTER_ROLE, msg.sender); supplyLimit = _supplyLimt; } - // constructor() ERC20("BE test USDT", "USDT") {} - - function pause() external onlyRole(PAUSER_ROLE) { - _pause(); - } - - function unpause() external onlyRole(PAUSER_ROLE) { - _unpause(); - } - function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) { if (supplyLimit > 0) { require( @@ -41,22 +28,6 @@ contract FT is ERC20, ERC20Burnable, Pausable, AccessControl { _mint(to, amount); } - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal override whenNotPaused { - super._beforeTokenTransfer(from, to, amount); - } - - function setPauserRole(address to) external { - grantRole(PAUSER_ROLE, to); - } - - function removePauserRole(address to) external { - revokeRole(PAUSER_ROLE, to); - } - function setMintRole(address to) external { grantRole(MINTER_ROLE, to); }