按审计要求修改合约
This commit is contained in:
parent
d9b7386f27
commit
0771e9162b
@ -4,93 +4,8 @@ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
|
|||||||
import "@openzeppelin/contracts/access/Ownable.sol";
|
import "@openzeppelin/contracts/access/Ownable.sol";
|
||||||
|
|
||||||
contract HasSignature is Ownable {
|
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;
|
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(
|
function checkSigner(
|
||||||
address signer,
|
address signer,
|
||||||
bytes32 hash,
|
bytes32 hash,
|
||||||
|
107
contracts/core/HasSignature712.sol
Normal file
107
contracts/core/HasSignature712.sol
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,8 +18,6 @@ contract UserMinterFactory is Ownable, TimeChecker, HasSignature {
|
|||||||
uint256[] ids
|
uint256[] ids
|
||||||
);
|
);
|
||||||
|
|
||||||
constructor() HasSignature("UserMinterFactory", "1") {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev mint nft by user
|
* @dev mint nft by user
|
||||||
*/
|
*/
|
||||||
|
@ -15,8 +15,6 @@ contract BENftMall is MallBase, ReentrancyGuard, HasSignature, TimeChecker {
|
|||||||
using SafeERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
using UInt for uint256;
|
using UInt for uint256;
|
||||||
|
|
||||||
constructor() HasSignature("NftMall", "1") {}
|
|
||||||
|
|
||||||
mapping(address => bool) public erc721Supported;
|
mapping(address => bool) public erc721Supported;
|
||||||
mapping(address => bool) public erc1155Supported;
|
mapping(address => bool) public erc1155Supported;
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ contract BENftMarket is Ownable, ReentrancyGuard, ERC1155Holder, ERC721Holder {
|
|||||||
*/
|
*/
|
||||||
function removeERC721Support(address nftToken) external onlyOwner {
|
function removeERC721Support(address nftToken) external onlyOwner {
|
||||||
erc721Supported[nftToken] = false;
|
erc721Supported[nftToken] = false;
|
||||||
erc1155SupportedHistory[nftToken] = true;
|
erc721SupportedHistory[nftToken] = true;
|
||||||
emit RemoveNFTSuppout(nftToken);
|
emit RemoveNFTSuppout(nftToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,8 +18,6 @@ contract GameItemMall is MallBase, ReentrancyGuard, HasSignature, TimeChecker {
|
|||||||
|
|
||||||
mapping(uint256 => address) public orderIdUsed;
|
mapping(uint256 => address) public orderIdUsed;
|
||||||
|
|
||||||
constructor() HasSignature("GameItemMarket", "1") {}
|
|
||||||
|
|
||||||
event ItemSoldOut(
|
event ItemSoldOut(
|
||||||
address indexed buyer,
|
address indexed buyer,
|
||||||
uint256 indexed orderId,
|
uint256 indexed orderId,
|
||||||
|
@ -28,8 +28,6 @@ contract GameItemMarket is
|
|||||||
// max transaction fee is: 10%
|
// max transaction fee is: 10%
|
||||||
uint256 public constant MAX_TRANSACTION_FEE = (10 * ROUND) / 100;
|
uint256 public constant MAX_TRANSACTION_FEE = (10 * ROUND) / 100;
|
||||||
|
|
||||||
constructor() HasSignature("GameItemMarket", "1") {}
|
|
||||||
|
|
||||||
event ItemSoldOut(
|
event ItemSoldOut(
|
||||||
address indexed buyer,
|
address indexed buyer,
|
||||||
address indexed seller,
|
address indexed seller,
|
||||||
|
@ -38,8 +38,6 @@ contract MarketPlace is Ownable, HasSignature {
|
|||||||
uint256 fee
|
uint256 fee
|
||||||
);
|
);
|
||||||
|
|
||||||
constructor() HasSignature("MarketPlace", "1") {}
|
|
||||||
|
|
||||||
function setFeeToAddress(address _feeToAddress) external onlyOwner {
|
function setFeeToAddress(address _feeToAddress) external onlyOwner {
|
||||||
require(
|
require(
|
||||||
_feeToAddress != address(0),
|
_feeToAddress != address(0),
|
||||||
@ -57,10 +55,9 @@ contract MarketPlace is Ownable, HasSignature {
|
|||||||
transactionFee = _transactionFee;
|
transactionFee = _transactionFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPaymentTokens(address[] calldata _paymentTokens)
|
function setPaymentTokens(
|
||||||
external
|
address[] calldata _paymentTokens
|
||||||
onlyOwner
|
) external onlyOwner {
|
||||||
{
|
|
||||||
for (uint256 i = 0; i < _paymentTokens.length; i++) {
|
for (uint256 i = 0; i < _paymentTokens.length; i++) {
|
||||||
if (paymentTokens[_paymentTokens[i]]) {
|
if (paymentTokens[_paymentTokens[i]]) {
|
||||||
continue;
|
continue;
|
||||||
@ -70,10 +67,9 @@ contract MarketPlace is Ownable, HasSignature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removePaymentTokens(address[] calldata _removedPaymentTokens)
|
function removePaymentTokens(
|
||||||
external
|
address[] calldata _removedPaymentTokens
|
||||||
onlyOwner
|
) external onlyOwner {
|
||||||
{
|
|
||||||
for (uint256 i = 0; i < _removedPaymentTokens.length; i++) {
|
for (uint256 i = 0; i < _removedPaymentTokens.length; i++) {
|
||||||
paymentTokens[_removedPaymentTokens[i]] = false;
|
paymentTokens[_removedPaymentTokens[i]] = false;
|
||||||
}
|
}
|
||||||
@ -165,9 +161,10 @@ contract MarketPlace is Ownable, HasSignature {
|
|||||||
/**
|
/**
|
||||||
* @dev Function to emit transaction matched event
|
* @dev Function to emit transaction matched event
|
||||||
*/
|
*/
|
||||||
function emitEvent(address[3] calldata addresses, uint256[3] calldata values)
|
function emitEvent(
|
||||||
internal
|
address[3] calldata addresses,
|
||||||
{
|
uint256[3] calldata values
|
||||||
|
) internal {
|
||||||
emit MatchTransaction(
|
emit MatchTransaction(
|
||||||
values[0],
|
values[0],
|
||||||
addresses[1],
|
addresses[1],
|
||||||
|
@ -2,11 +2,9 @@
|
|||||||
pragma solidity 0.8.10;
|
pragma solidity 0.8.10;
|
||||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||||
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
|
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
|
||||||
import "@openzeppelin/contracts/security/Pausable.sol";
|
|
||||||
import "@openzeppelin/contracts/access/AccessControl.sol";
|
import "@openzeppelin/contracts/access/AccessControl.sol";
|
||||||
|
|
||||||
contract FT is ERC20, ERC20Burnable, Pausable, AccessControl {
|
contract FT is ERC20, ERC20Burnable, AccessControl {
|
||||||
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
|
|
||||||
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
|
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
|
||||||
uint256 public immutable supplyLimit;
|
uint256 public immutable supplyLimit;
|
||||||
|
|
||||||
@ -16,21 +14,10 @@ contract FT is ERC20, ERC20Burnable, Pausable, AccessControl {
|
|||||||
uint256 _supplyLimt
|
uint256 _supplyLimt
|
||||||
) ERC20(name_, symbol_) {
|
) ERC20(name_, symbol_) {
|
||||||
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
|
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
|
||||||
_setupRole(PAUSER_ROLE, msg.sender);
|
|
||||||
_setupRole(MINTER_ROLE, msg.sender);
|
_setupRole(MINTER_ROLE, msg.sender);
|
||||||
supplyLimit = _supplyLimt;
|
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) {
|
function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) {
|
||||||
if (supplyLimit > 0) {
|
if (supplyLimit > 0) {
|
||||||
require(
|
require(
|
||||||
@ -41,22 +28,6 @@ contract FT is ERC20, ERC20Burnable, Pausable, AccessControl {
|
|||||||
_mint(to, amount);
|
_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 {
|
function setMintRole(address to) external {
|
||||||
grantRole(MINTER_ROLE, to);
|
grantRole(MINTER_ROLE, to);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user