使用prettier格式化代码

This commit is contained in:
cebgcontract 2022-08-18 10:54:42 +08:00
parent cbf5712881
commit 69681b8106
28 changed files with 1632 additions and 1579 deletions

15
.prettierrc.json Normal file
View File

@ -0,0 +1,15 @@
{
"overrides": [
{
"files": "*.sol",
"options": {
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false,
"explicitTypes": "always"
}
}
]
}

View File

@ -3,7 +3,7 @@ pragma solidity 0.8.10;
contract Migrations {
address public owner = msg.sender;
uint public last_completed_migration;
uint256 public last_completed_migration;
modifier restricted() {
require(
@ -13,7 +13,7 @@ contract Migrations {
_;
}
function setCompleted(uint completed) external restricted {
function setCompleted(uint256 completed) external restricted {
last_completed_migration = completed;
}

View File

@ -7,39 +7,51 @@ contract BETimelockController is TimelockController {
uint256 public constant MAX_DELAY = 16 days;
uint256 private _minDelay;
constructor(
address[] memory proposers,
address[] memory executors)
TimelockController(MIN_DELAY, proposers, executors){
_minDelay = MIN_DELAY;
constructor(address[] memory proposers, address[] memory executors)
TimelockController(MIN_DELAY, proposers, executors)
{
_minDelay = MIN_DELAY;
}
/**
* @dev Returns the minimum delay for an operation to become valid.
*
* This value can be changed by executing an operation that calls `updateDelay`.
*/
function getMinDelay()
public
view
virtual
override
returns (uint256 duration)
{
return _minDelay;
}
/**
* @dev Returns the minimum delay for an operation to become valid.
*
* This value can be changed by executing an operation that calls `updateDelay`.
*/
function getMinDelay() public view virtual override returns (uint256 duration) {
return _minDelay;
}
/**
* @dev Changes the minimum timelock duration for future operations.
*
* Emits a {MinDelayChange} event.
*
* Requirements:
*
* - the caller must be the timelock itself. This can only be achieved by scheduling and later executing
* an operation where the timelock is the target and the data is the ABI-encoded call to this function.
*/
function updateDelay(uint256 newDelay) external virtual override {
require(msg.sender == address(this), "BETimelockController: caller must be timelock");
require(newDelay >= MIN_DELAY, "BETimelockController: newDelay must greater than or equal to MIN_DELAY");
require(newDelay <= MAX_DELAY, "BETimelockController: newDelay must less than or equal to MAX_DELAY");
emit MinDelayChange(_minDelay, newDelay);
_minDelay = newDelay;
}
* @dev Changes the minimum timelock duration for future operations.
*
* Emits a {MinDelayChange} event.
*
* Requirements:
*
* - the caller must be the timelock itself. This can only be achieved by scheduling and later executing
* an operation where the timelock is the target and the data is the ABI-encoded call to this function.
*/
function updateDelay(uint256 newDelay) external virtual override {
require(
msg.sender == address(this),
"BETimelockController: caller must be timelock"
);
require(
newDelay >= MIN_DELAY,
"BETimelockController: newDelay must greater than or equal to MIN_DELAY"
);
require(
newDelay <= MAX_DELAY,
"BETimelockController: newDelay must less than or equal to MAX_DELAY"
);
emit MinDelayChange(_minDelay, newDelay);
_minDelay = newDelay;
}
}

View File

@ -4,136 +4,123 @@ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "../utils/Approval.sol";
contract HasSignature is Ownable, Approval{
bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
uint256 private immutable _CACHED_CHAIN_ID;
address private immutable _CACHED_THIS;
contract HasSignature is Ownable, Approval {
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;
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;
}
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)
)
);
}
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 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);
}
/**
* @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{
bytes32 digest = _hashTypedDataV4(structHash);
address recovered = ECDSA.recover(digest, signature);
require(recovered == signer, "[BE] invalid signature");
require(signer != address(0), "ECDSA: invalid signature");
}
function checkSigner712(
address signer,
bytes32 structHash,
bytes memory signature
) public view {
bytes32 digest = _hashTypedDataV4(structHash);
address recovered = ECDSA.recover(digest, signature);
require(recovered == signer, "[BE] invalid signature");
require(signer != address(0), "ECDSA: invalid signature");
}
function checkSigner(
address signer,
bytes32 hash,
bytes memory signature
) public pure {
require(signature.length == 65, "[BE] invalid signature length");
bytes32 ethSignedMessageHash = ECDSA.toEthSignedMessageHash(
hash
);
address recovered = ECDSA.recover(ethSignedMessageHash, signature);
require(recovered == signer, "[BE] invalid signature");
function checkSigner(
address signer,
bytes32 hash,
bytes memory signature
) public pure {
require(signature.length == 65, "[BE] invalid signature length");
bytes32 ethSignedMessageHash = ECDSA.toEthSignedMessageHash(hash);
address recovered = ECDSA.recover(ethSignedMessageHash, signature);
require(recovered == signer, "[BE] invalid signature");
}
modifier signatureValid(bytes calldata signature) {
require(
!_usedSignatures[signature],
"signature used. please send another transaction with new signature"
);
_;
}
/**
* @dev mark signature used
*/
function useSignature(bytes calldata signature) public approvaled {
if (!_usedSignatures[signature]) {
_usedSignatures[signature] = true;
}
modifier signatureValid(
bytes calldata signature
) {
require(
!_usedSignatures[signature],
"signature used. please send another transaction with new signature"
);
_;
}
/**
* @dev mark signature used
*/
function useSignature(
bytes calldata signature
) public approvaled {
if (!_usedSignatures[signature]) {
_usedSignatures[signature] = true;
}
}
}
}

View File

@ -4,20 +4,23 @@ pragma solidity 0.8.10;
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
interface IBEERC1155 is IERC1155 {
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) external;
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) external;
function burnBatch(
address owner,
uint256[] memory ids,
uint256[] memory values
) external;
function burnBatch(
address owner,
uint256[] memory ids,
uint256[] memory values
) external;
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOf(address account, uint256 id)
external
view
returns (uint256);
function canMint(uint256 id) external view returns (bool);
function canMint(uint256 id) external view returns (bool);
}

View File

@ -3,10 +3,10 @@ pragma solidity 0.8.10;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
interface IBEERC721 is IERC721 {
function mint(address to, uint256 tokenId) external;
function burn(address owner, uint256 tokenId) external;
function ownerOf(uint256 tokenId) external view returns (address owner);
function mint(address to, uint256 tokenId) external;
function burn(address owner, uint256 tokenId) external;
function ownerOf(uint256 tokenId) external view returns (address owner);
}

View File

@ -19,9 +19,7 @@ interface IEvolveFactory {
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external;
function useSignature(
bytes calldata signature
) external;
function useSignature(bytes calldata signature) external;
}

View File

@ -18,14 +18,9 @@ contract EvolveFactory is Ownable, TimeChecker, Initializable, HasSignature {
address public executor;
event TokenEvolved(
address indexed owner,
uint256[] tokenIds
);
event TokenEvolved(address indexed owner, uint256[] tokenIds);
constructor()
HasSignature("EvolveFactory", "1"){
}
constructor() HasSignature("EvolveFactory", "1") {}
function init(address chipAddress) external initializer onlyOwner {
chip = IBEERC1155(chipAddress);
@ -35,7 +30,7 @@ contract EvolveFactory is Ownable, TimeChecker, Initializable, HasSignature {
* @dev update executor
*/
function updateExecutor(address account) external onlyOwner {
require(account != address(0), 'address can not be zero');
require(account != address(0), "address can not be zero");
executor = account;
}
@ -46,9 +41,9 @@ contract EvolveFactory is Ownable, TimeChecker, Initializable, HasSignature {
uint256 saltNonce,
bytes calldata signature,
IBEERC721 nft
) external signatureValid(signature) timeValid(startTime){
) external signatureValid(signature) timeValid(startTime) {
require(
tokenIds[0] > 0 && tokenIds[1] > 0,
tokenIds[0] > 0 && tokenIds[1] > 0,
"EvolveFactory: token to evolve and burn can not be 0"
);
@ -69,7 +64,7 @@ contract EvolveFactory is Ownable, TimeChecker, Initializable, HasSignature {
}
uint256[] memory signArray = new uint256[](3);
for (uint256 i = 0; i < tokenIds.length; ++ i) {
for (uint256 i = 0; i < tokenIds.length; ++i) {
uint256 _id = tokenIds[i];
signArray[i] = _id;
}
@ -83,15 +78,14 @@ contract EvolveFactory is Ownable, TimeChecker, Initializable, HasSignature {
nft.burn(to, tokenIds[1]);
if (tokenIds[2] > 0) {
uint256 amount = 1;
chip.burnBatch(to,
tokenIds[2].asSingletonArray(),
amount.asSingletonArray());
chip.burnBatch(
to,
tokenIds[2].asSingletonArray(),
amount.asSingletonArray()
);
}
useSignature(signature);
emit TokenEvolved(
to,
signArray
);
emit TokenEvolved(to, signArray);
}
function evolveChip(
@ -100,14 +94,14 @@ contract EvolveFactory is Ownable, TimeChecker, Initializable, HasSignature {
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external signatureValid(signature) timeValid(startTime){
) external signatureValid(signature) timeValid(startTime) {
require(to != address(0), "EvolveFacrory: address is zero address");
uint256 len = tokenIds.length;
uint256[] memory amounts = new uint256[](len -1);
uint256[] memory amounts = new uint256[](len - 1);
uint256[] memory idsForBurn = new uint256[](len - 1);
for (uint256 i = 0; i < len; ++ i) {
for (uint256 i = 0; i < len; ++i) {
require(
chip.balanceOf(to, tokenIds[i]) > 0,
chip.balanceOf(to, tokenIds[i]) > 0,
"EvolveFacrory: Chip specified not exists"
);
if (i > 0) {
@ -115,15 +109,17 @@ contract EvolveFactory is Ownable, TimeChecker, Initializable, HasSignature {
amounts[i - 1] = 1;
}
}
bytes32 criteriaMessageHash = getMessageHash(to, startTime, saltNonce, tokenIds);
bytes32 criteriaMessageHash = getMessageHash(
to,
startTime,
saltNonce,
tokenIds
);
checkSigner(executor, criteriaMessageHash, signature);
chip.burnBatch(to, idsForBurn, amounts);
useSignature(signature);
emit TokenEvolved(
to,
tokenIds
);
}
emit TokenEvolved(to, tokenIds);
}
function getMessageHash(
address _to,
@ -138,5 +134,4 @@ contract EvolveFactory is Ownable, TimeChecker, Initializable, HasSignature {
}
return keccak256(encoded);
}
}

View File

@ -12,285 +12,299 @@ import "../utils/TimeChecker.sol";
import "../core/HasSignature.sol";
import "./FactoryBase.sol";
contract MinterFactory is Ownable, FactoryBase, TimeChecker, Initializable, HasSignature {
using UInt for uint256;
using SafeERC20 for IERC20;
address public executor;
// NFT contract
IBEERC721 public hero;
IBEERC721 public equip;
IBEERC1155 public chip;
IBEERC1155 public shard;
contract MinterFactory is
Ownable,
FactoryBase,
TimeChecker,
Initializable,
HasSignature
{
using UInt for uint256;
using SafeERC20 for IERC20;
address public executor;
// NFT contract
IBEERC721 public hero;
IBEERC721 public equip;
IBEERC1155 public chip;
IBEERC1155 public shard;
address public feeToAddress;
address public feeToAddress;
event TokenMinted(
address contractAddress,
address to,
uint256 indexed tokenId
event TokenMinted(
address contractAddress,
address to,
uint256 indexed tokenId
);
event TokenMintedBatch(
address contractAddress,
address indexed to,
uint256[] ids,
uint256[] amounts
);
constructor() HasSignature("MinterFactory", "1") {}
function init(address[4] calldata _erc721s) external initializer onlyOwner {
hero = IBEERC721(_erc721s[0]);
equip = IBEERC721(_erc721s[1]);
chip = IBEERC1155(_erc721s[2]);
shard = IBEERC1155(_erc721s[3]);
}
/**
* @dev update executor
*/
function updateExecutor(address account) external onlyOwner {
require(account != address(0), "address can not be zero");
executor = account;
}
function setFeeToAddress(address _feeToAddress) external onlyOwner {
require(
_feeToAddress != address(0),
"fee received address can not be zero"
);
feeToAddress = _feeToAddress;
}
/**
* @dev mint function to distribute Hero NFT to user
*/
function mintHeroTo(address to, uint256 tokenId) external onlyOwner {
mint721NFT(to, tokenId, hero);
}
/**
* @dev mint function to distribute Equipment NFT to user
*/
function mintEquipTo(address to, uint256 tokenId) external onlyOwner {
mint721NFT(to, tokenId, equip);
}
/**
* @dev mint function to distribute Chip NFT to user
*/
function mintChipTo(address to, uint256 tokenId) external onlyOwner {
mint1155NFT(to, tokenId, 1, chip);
}
/**
* @dev mint function to distribute Shard NFT to user
*/
function mintShardTo(address to, uint256 tokenId) external onlyOwner {
mint1155NFT(to, tokenId, 1, shard);
}
/**
* @dev batch mint 1155 Chip to user
*/
function mintChipBatch(address to, uint256[] memory ids) external onlyOwner {
require(
to != address(0),
"MinterFactory::mintChipBatch: to address can not be zero"
);
require(
ids.length > 0,
"MinterFactory::mintChipBatch: ids cannot be empty"
);
uint256[] memory amounts = new uint256[](ids.length);
uint256 len = ids.length;
for (uint256 i = 0; i < len; ++i) {
amounts[i] = 1;
}
mint1155NFTBatch(to, ids, amounts, chip);
}
/**
* @dev batch mint 1155 Shard to user
*/
function mintShardBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts
) external onlyOwner {
require(to != address(0), "MinterFactory: to address can not be zero");
require(ids.length > 0, "MinterFactory: ids cannot be empty");
require(
ids.length == amounts.length,
"MinterFactory: ids and amounts length mismatch"
);
mint1155NFTBatch(to, ids, amounts, shard);
}
function mint721ByUser(
address to,
uint256 id,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature,
IBEERC721 nft
) external signatureValid(signature) timeValid(startTime) {
uint256[] memory signArray = new uint256[](1);
signArray[0] = id;
bytes32 criteriaMessageHash = getMessageHash(
to,
address(nft),
startTime,
saltNonce,
signArray
);
checkSigner(executor, criteriaMessageHash, signature);
mint721NFT(to, id, nft);
useSignature(signature);
}
function mint1155BatchByUser(
address to,
uint256[] memory ids,
uint256[] memory amounts,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature,
IBEERC1155 nft
) external signatureValid(signature) timeValid(startTime) {
uint256 len = ids.length;
require(len > 0, "MinterFactory: ids cannot be empty");
require(
len == amounts.length,
"MinterFactory: ids and amounts length mismatch"
);
uint256[] memory signArray = new uint256[](len * 2);
for (uint256 i = 0; i < len; ++i) {
require(
nft.canMint(ids[i]),
"MinterFactory: can not mint for current nft rule setting"
);
signArray[i * 2] = ids[i];
signArray[i * 2 + 1] = amounts[i];
}
bytes32 criteriaMessageHash = getMessageHash(
to,
address(nft),
startTime,
saltNonce,
signArray
);
checkSigner(executor, criteriaMessageHash, signature);
mint1155NFTBatch(to, ids, amounts, nft);
useSignature(signature);
}
function shardMixByUser(
ShardParam memory param,
uint256[] memory ids,
uint256[] memory amounts,
bytes calldata signature,
IBEERC721 nft
) external signatureValid(signature) timeValid(param.startTime) {
require(ids.length > 0, "MinterFactory: ids cannot be empty");
require(
ids.length == amounts.length,
"MinterFactory: ids and amounts length mismatch"
);
event TokenMintedBatch(
address contractAddress,
address indexed to,
uint256[] ids,
uint256[] amounts
uint256[] memory signArray = new uint256[](ids.length * 2);
for (uint256 i = 0; i < ids.length; ++i) {
require(
shard.balanceOf(param.to, ids[i]) > 0,
"MinterFactory: not enough shard"
);
signArray[i * 2] = ids[i];
signArray[i * 2 + 1] = amounts[i];
}
bytes32 criteriaMessageHash = getShardMixHash(
param,
address(nft),
signArray
);
checkSigner(executor, criteriaMessageHash, signature);
// Check payment approval and buyer balance
IERC20 paymentContract = IERC20(param.payToken);
require(
paymentContract.balanceOf(param.to) >= param.payAmount,
"MinterFactory: doesn't have enough token to mix shard"
);
require(
paymentContract.allowance(param.to, address(this)) >= param.payAmount,
"MinterFactory: doesn't approve MinterFactory to spend payment amount"
);
// transfer money to address
paymentContract.safeTransferFrom(param.to, feeToAddress, param.payAmount);
shard.burnBatch(param.to, ids, amounts);
mint721NFT(param.to, param.nftId, nft);
useSignature(signature);
}
function mint721NFT(
address to,
uint256 tokenId,
IBEERC721 nft
) internal {
require(to != address(0), "MinterFactory: to address can not be zero");
nft.mint(to, tokenId);
emit TokenMinted(address(nft), to, tokenId);
}
constructor() HasSignature("MinterFactory", "1") {}
function mint1155NFT(
address to,
uint256 id,
uint256 amount,
IBEERC1155 nft
) internal {
require(to != address(0), "MinterFactory: to address can not be zero");
nft.mintBatch(to, id.asSingletonArray(), amount.asSingletonArray(), "");
emit TokenMinted(address(chip), to, id);
}
function init(address[4] calldata _erc721s) external initializer onlyOwner {
hero = IBEERC721(_erc721s[0]);
equip = IBEERC721(_erc721s[1]);
chip = IBEERC1155(_erc721s[2]);
shard = IBEERC1155(_erc721s[3]);
function mint1155NFTBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
IBEERC1155 nft
) internal {
nft.mintBatch(to, ids, amounts, "");
emit TokenMintedBatch(address(nft), to, ids, amounts);
}
function getMessageHash(
address _to,
address _nftAddress,
uint256 _startTime,
uint256 _saltNonce,
uint256[] memory _ids
) public pure returns (bytes32) {
bytes memory encoded = abi.encodePacked(
_to,
_nftAddress,
_startTime,
_saltNonce
);
uint256 len = _ids.length;
for (uint256 i = 0; i < len; ++i) {
encoded = bytes.concat(encoded, abi.encodePacked(_ids[i]));
}
return keccak256(encoded);
}
/**
* @dev update executor
*/
function updateExecutor(address account) external onlyOwner {
require(account != address(0), "address can not be zero");
executor = account;
}
function setFeeToAddress(address _feeToAddress) external onlyOwner {
require(_feeToAddress != address(0), 'fee received address can not be zero');
feeToAddress = _feeToAddress;
}
/**
* @dev mint function to distribute Hero NFT to user
*/
function mintHeroTo(address to, uint256 tokenId) external onlyOwner {
mint721NFT(to, tokenId, hero);
}
/**
* @dev mint function to distribute Equipment NFT to user
*/
function mintEquipTo(address to, uint256 tokenId) external onlyOwner {
mint721NFT(to, tokenId, equip);
}
/**
* @dev mint function to distribute Chip NFT to user
*/
function mintChipTo(address to, uint256 tokenId) external onlyOwner {
mint1155NFT(to, tokenId, 1, chip);
}
/**
* @dev mint function to distribute Shard NFT to user
*/
function mintShardTo(address to, uint256 tokenId) external onlyOwner {
mint1155NFT(to, tokenId, 1, shard);
}
/**
* @dev batch mint 1155 Chip to user
*/
function mintChipBatch(address to, uint256[] memory ids)
external
onlyOwner
{
require(
to != address(0),
"MinterFactory::mintChipBatch: to address can not be zero"
);
require(
ids.length > 0,
"MinterFactory::mintChipBatch: ids cannot be empty"
);
uint256[] memory amounts = new uint256[](ids.length);
uint256 len = ids.length;
for (uint256 i = 0; i < len; ++i) {
amounts[i] = 1;
}
mint1155NFTBatch(to, ids, amounts, chip);
}
/**
* @dev batch mint 1155 Shard to user
*/
function mintShardBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts
) external onlyOwner {
require(to != address(0), "MinterFactory: to address can not be zero");
require(ids.length > 0, "MinterFactory: ids cannot be empty");
require(
ids.length == amounts.length,
"MinterFactory: ids and amounts length mismatch"
);
mint1155NFTBatch(to, ids, amounts, shard);
}
function mint721ByUser(
address to,
uint256 id,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature,
IBEERC721 nft
) external signatureValid(signature) timeValid(startTime){
uint256[] memory signArray = new uint256[](1);
signArray[0] = id;
bytes32 criteriaMessageHash =
getMessageHash(to, address(nft), startTime, saltNonce, signArray);
checkSigner(executor, criteriaMessageHash, signature);
mint721NFT(to, id, nft);
useSignature(signature);
}
function mint1155BatchByUser(
address to,
uint256[] memory ids,
uint256[] memory amounts,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature,
IBEERC1155 nft
) external signatureValid(signature) timeValid(startTime){
uint256 len = ids.length;
require(len > 0, "MinterFactory: ids cannot be empty");
require(
len == amounts.length,
"MinterFactory: ids and amounts length mismatch"
);
uint256[] memory signArray = new uint256[](len * 2);
for (uint256 i = 0; i < len; ++i) {
require(
nft.canMint(ids[i]),
"MinterFactory: can not mint for current nft rule setting"
);
signArray[i * 2] = ids[i];
signArray[i * 2 + 1] = amounts[i];
}
bytes32 criteriaMessageHash =
getMessageHash(to, address(nft), startTime, saltNonce, signArray);
checkSigner(executor, criteriaMessageHash, signature);
mint1155NFTBatch(to, ids, amounts, nft);
useSignature(signature);
}
function shardMixByUser(
ShardParam memory param,
uint256[] memory ids,
uint256[] memory amounts,
bytes calldata signature,
IBEERC721 nft
) external signatureValid(signature) timeValid(param.startTime) {
require(ids.length > 0, "MinterFactory: ids cannot be empty");
require(
ids.length == amounts.length,
"MinterFactory: ids and amounts length mismatch"
);
uint256[] memory signArray = new uint256[](ids.length * 2);
for (uint256 i = 0; i < ids.length; ++i) {
require(
shard.balanceOf(param.to, ids[i]) > 0,
"MinterFactory: not enough shard"
);
signArray[i * 2] = ids[i];
signArray[i * 2 + 1] = amounts[i];
}
bytes32 criteriaMessageHash =
getShardMixHash(param, address(nft), signArray);
checkSigner(executor, criteriaMessageHash, signature);
// Check payment approval and buyer balance
IERC20 paymentContract = IERC20(param.payToken);
require(
paymentContract.balanceOf(param.to) >= param.payAmount,
"MinterFactory: doesn't have enough token to mix shard"
);
require(
paymentContract.allowance(param.to, address(this)) >= param.payAmount,
"MinterFactory: doesn't approve MinterFactory to spend payment amount"
);
// transfer money to address
paymentContract.safeTransferFrom(
param.to,
feeToAddress,
param.payAmount
);
shard.burnBatch(param.to, ids, amounts);
mint721NFT(param.to, param.nftId, nft);
useSignature(signature);
}
function mint721NFT(
address to,
uint256 tokenId,
IBEERC721 nft
) internal {
require(to != address(0), "MinterFactory: to address can not be zero");
nft.mint(to, tokenId);
emit TokenMinted(address(nft), to, tokenId);
}
function mint1155NFT(
address to,
uint256 id,
uint256 amount,
IBEERC1155 nft
) internal {
require(to != address(0), "MinterFactory: to address can not be zero");
nft.mintBatch(to, id.asSingletonArray(), amount.asSingletonArray(), "");
emit TokenMinted(address(chip), to, id);
}
function mint1155NFTBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
IBEERC1155 nft
) internal {
nft.mintBatch(to, ids, amounts, "");
emit TokenMintedBatch(address(nft), to, ids, amounts);
}
function getMessageHash(
address _to,
address _nftAddress,
uint256 _startTime,
uint256 _saltNonce,
uint256[] memory _ids
) public pure returns (bytes32) {
bytes memory encoded =
abi.encodePacked(_to, _nftAddress, _startTime, _saltNonce);
uint256 len = _ids.length;
for (uint256 i = 0; i < len; ++i) {
encoded = bytes.concat(encoded, abi.encodePacked(_ids[i]));
}
return keccak256(encoded);
}
function getShardMixHash(
ShardParam memory param,
address nftAddress,
uint256[] memory _ids
) internal pure returns (bytes32) {
bytes memory encoded =
abi.encodePacked(
param.to,
nftAddress,
param.nftId,
param.payToken,
param.payAmount,
param.startTime,
param.saltNonce
);
uint256 len = _ids.length;
for (uint256 i = 0; i < len; ++i) {
encoded = bytes.concat(encoded, abi.encodePacked(_ids[i]));
}
return keccak256(encoded);
function getShardMixHash(
ShardParam memory param,
address nftAddress,
uint256[] memory _ids
) internal pure returns (bytes32) {
bytes memory encoded = abi.encodePacked(
param.to,
nftAddress,
param.nftId,
param.payToken,
param.payAmount,
param.startTime,
param.saltNonce
);
uint256 len = _ids.length;
for (uint256 i = 0; i < len; ++i) {
encoded = bytes.concat(encoded, abi.encodePacked(_ids[i]));
}
return keccak256(encoded);
}
}

View File

@ -8,165 +8,153 @@ import "../interfaces/IBEERC721.sol";
import "../core/HasSignature.sol";
contract MysteryBoxProxy is Ownable, Initializable, HasSignature {
IBEERC721 public box;
IBEERC721 public hero;
IBEERC721 public equip;
IBEERC721 public chip;
IBEERC721 public box;
IBEERC721 public hero;
IBEERC721 public equip;
IBEERC721 public chip;
uint8 public constant TYPE_NONE = 0;
uint8 public constant TYPE_HERO = 1;
uint8 public constant TYPE_EQUIP = 2;
uint8 public constant TYPE_CHIP = 3;
uint8 public constant TYPE_NONE = 0;
uint8 public constant TYPE_HERO = 1;
uint8 public constant TYPE_EQUIP = 2;
uint8 public constant TYPE_CHIP = 3;
address public executor;
address public executor;
mapping(bytes => bool) public usedSignatures;
mapping(bytes => bool) public usedSignatures;
event TokenMinted(
address contractAddress,
address to,
uint256 indexed tokenId
event TokenMinted(
address contractAddress,
address to,
uint256 indexed tokenId
);
event BoxOpened(
address indexed to,
uint256 indexed boxId,
uint256 val,
uint256[3] ids,
uint8[3] types
);
constructor() HasSignature("MysteryBoxProxy", "1") {}
function init(address[4] calldata _erc721s) external initializer onlyOwner {
hero = IBEERC721(_erc721s[0]);
equip = IBEERC721(_erc721s[1]);
chip = IBEERC721(_erc721s[2]);
box = IBEERC721(_erc721s[3]);
}
/**
* @dev update executor
*/
function updateExecutor(address account) external onlyOwner {
require(account != address(0), "address can not be zero");
executor = account;
}
function mintBoxTo(address to, uint256 tokenId) external onlyOwner {
require(to != address(0), "to address can not be zero");
box.mint(to, tokenId);
emit TokenMinted(address(box), to, tokenId);
}
function openBox(
uint256 boxId,
uint256[3] calldata ids,
uint256 saltNonce,
bytes calldata signature
) external {
require(ids.length == 3, "MysteryBoxProxy: amount of token id mismatch");
require(
!usedSignatures[signature],
"MysteryBoxProxy: signature used. please send another transaction with new signature"
);
event BoxOpened(
address indexed to,
uint256 indexed boxId,
uint256 val,
uint256[3] ids,
uint8[3] types
address owner = msg.sender;
require(
box.ownerOf(boxId) == owner,
"MysteryBoxProxy: only owner can open this box"
);
bytes32 criteriaMessageHash = getMessageHash(
boxId,
ids[0],
ids[1],
ids[2],
saltNonce
);
checkSigner(executor, criteriaMessageHash, signature);
// open box
box.burn(owner, boxId);
usedSignatures[signature] = true;
constructor() HasSignature("MysteryBoxProxy", "1") {}
uint256[3] memory results = [ids[0], 0, 0];
uint8[3] memory types = [TYPE_HERO, TYPE_NONE, TYPE_NONE];
mint721WithType(owner, ids[0], types[0]);
results[0] = ids[0];
function init(address[4] calldata _erc721s)
external
initializer
onlyOwner
{
hero = IBEERC721(_erc721s[0]);
equip = IBEERC721(_erc721s[1]);
chip = IBEERC721(_erc721s[2]);
box = IBEERC721(_erc721s[3]);
uint256 val = rand(owner, saltNonce, 100);
if (val >= 70 && val < 90) {
types[1] = TYPE_CHIP;
mint721WithType(owner, ids[1], types[1]);
results[1] = ids[1];
} else if (val >= 90 && val < 98) {
types[1] = TYPE_EQUIP;
mint721WithType(owner, ids[1], types[1]);
results[1] = ids[1];
} else if (val >= 98) {
types[1] = TYPE_EQUIP;
mint721WithType(owner, ids[1], types[1]);
results[1] = ids[1];
types[2] = TYPE_CHIP;
mint721WithType(owner, ids[2], types[2]);
results[2] = ids[2];
}
emit BoxOpened(owner, boxId, val, results, types);
}
/**
* @dev update executor
*/
function updateExecutor(address account) external onlyOwner {
require(account != address(0), "address can not be zero");
executor = account;
function mint721WithType(
address to,
uint256 tokenId,
uint256 typeNum
) private {
if (typeNum == 1) {
hero.mint(to, tokenId);
} else if (typeNum == 2) {
equip.mint(to, tokenId);
} else if (typeNum == 3) {
chip.mint(to, tokenId);
}
}
function mintBoxTo(address to, uint256 tokenId) external onlyOwner{
require(to != address(0), 'to address can not be zero');
box.mint(to, tokenId);
emit TokenMinted(address(box), to, tokenId);
}
function rand(
address owner,
uint256 nonce,
uint256 _length
) internal view returns (uint256) {
uint256 random = uint256(
keccak256(
abi.encodePacked(owner, nonce, block.difficulty, block.timestamp)
)
);
return random % _length;
}
function openBox(
uint256 boxId,
uint256[3] calldata ids,
uint256 saltNonce,
bytes calldata signature
) external {
require(
ids.length == 3,
"MysteryBoxProxy: amount of token id mismatch"
);
require(
!usedSignatures[signature],
"MysteryBoxProxy: signature used. please send another transaction with new signature"
);
address owner = msg.sender;
require(
box.ownerOf(boxId) == owner,
"MysteryBoxProxy: only owner can open this box"
);
bytes32 criteriaMessageHash = getMessageHash(
boxId,
ids[0],
ids[1],
ids[2],
saltNonce
);
checkSigner(executor, criteriaMessageHash, signature);
// open box
box.burn(owner, boxId);
usedSignatures[signature] = true;
uint256[3] memory results = [ids[0], 0, 0];
uint8[3] memory types = [TYPE_HERO, TYPE_NONE, TYPE_NONE];
mint721WithType(owner, ids[0], types[0]);
results[0] = ids[0];
uint256 val = rand(owner, saltNonce, 100);
if (val >= 70 && val < 90) {
types[1] = TYPE_CHIP;
mint721WithType(owner, ids[1], types[1]);
results[1] = ids[1];
} else if (val >= 90 && val < 98) {
types[1] = TYPE_EQUIP;
mint721WithType(owner, ids[1], types[1]);
results[1] = ids[1];
} else if (val >= 98) {
types[1] = TYPE_EQUIP;
mint721WithType(owner, ids[1], types[1]);
results[1] = ids[1];
types[2] = TYPE_CHIP;
mint721WithType(owner, ids[2], types[2]);
results[2] = ids[2];
}
emit BoxOpened(owner, boxId, val, results, types);
}
function mint721WithType(
address to,
uint256 tokenId,
uint256 typeNum
) private {
if (typeNum == 1) {
hero.mint(to, tokenId);
} else if (typeNum == 2) {
equip.mint(to, tokenId);
} else if (typeNum == 3) {
chip.mint(to, tokenId);
}
}
function rand(
address owner,
uint256 nonce,
uint256 _length
) internal view returns (uint256) {
uint256 random = uint256(
keccak256(
abi.encodePacked(
owner,
nonce,
block.difficulty,
block.timestamp
)
)
);
return random % _length;
}
function getMessageHash(
uint256 _boxId,
uint256 _firstToken,
uint256 _secondToken,
uint256 _thirdToken,
uint256 _saltNonce
) public pure returns (bytes32) {
return
keccak256(
abi.encodePacked(
_boxId,
_firstToken,
_secondToken,
_thirdToken,
_saltNonce
)
);
}
function getMessageHash(
uint256 _boxId,
uint256 _firstToken,
uint256 _secondToken,
uint256 _thirdToken,
uint256 _saltNonce
) public pure returns (bytes32) {
return
keccak256(
abi.encodePacked(
_boxId,
_firstToken,
_secondToken,
_thirdToken,
_saltNonce
)
);
}
}

View File

@ -10,7 +10,7 @@ contract UserEvolveFactory is Ownable, Initializable {
IBEERC721 public hero;
IBEERC721 public equip;
event TokenEvolveFail (
event TokenEvolveFail(
address indexed to,
bytes signature,
string reason,
@ -23,114 +23,83 @@ contract UserEvolveFactory is Ownable, Initializable {
factory = IEvolveFactory(_nfts[2]);
}
/**
/**
* @dev evolve function Hero NFT
* tokenIds: [hero_to_evolve, hero_for_burn, chip]
*/
function evolveHero(
uint256[3] calldata tokenIds,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external returns (bool success){
uint256[3] calldata tokenIds,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external returns (bool success) {
address to = _msgSender();
try factory.evolve721NFT(to, tokenIds, startTime, saltNonce, signature, hero) {
try
factory.evolve721NFT(to, tokenIds, startTime, saltNonce, signature, hero)
{
return true;
} catch Error(string memory reason) {
bytes memory by;
factory.useSignature(signature);
emit TokenEvolveFail(
to,
signature,
reason,
by
);
emit TokenEvolveFail(to, signature, reason, by);
return false;
} catch (bytes memory lowLevelData) {
factory.useSignature(signature);
string memory reason;
emit TokenEvolveFail(
to,
signature,
reason,
lowLevelData
);
return false;
}
}
/**
* @dev evolve function for equip NFT
* tokenIds: [equip_to_evolve, equip_for_burn, chip]
*/
function evolveEquip(
uint256[3] calldata tokenIds,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external returns (bool success){
address to = _msgSender();
try factory.evolve721NFT(to, tokenIds, startTime, saltNonce, signature, equip) {
return true;
} catch Error(string memory reason) {
bytes memory by;
factory.useSignature(signature);
emit TokenEvolveFail(
to,
signature,
reason,
by
);
return false;
} catch (bytes memory lowLevelData) {
factory.useSignature(signature);
string memory reason;
emit TokenEvolveFail(
to,
signature,
reason,
lowLevelData
);
emit TokenEvolveFail(to, signature, reason, lowLevelData);
return false;
}
}
/**
* @dev evolve function for chip
* @dev evolve function for equip NFT
* tokenIds: [equip_to_evolve, equip_for_burn, chip]
*/
function evolveChip(
uint256[] memory ids,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external returns (bool success){
function evolveEquip(
uint256[3] calldata tokenIds,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external returns (bool success) {
address to = _msgSender();
try factory.evolveChip(
to,
ids,
startTime,
saltNonce,
signature
) {
try
factory.evolve721NFT(to, tokenIds, startTime, saltNonce, signature, equip)
{
return true;
} catch Error(string memory reason) {
bytes memory by;
factory.useSignature(signature);
emit TokenEvolveFail(
to,
signature,
reason,
by
);
emit TokenEvolveFail(to, signature, reason, by);
return false;
} catch (bytes memory lowLevelData) {
factory.useSignature(signature);
string memory reason;
emit TokenEvolveFail(
to,
signature,
reason,
lowLevelData
);
emit TokenEvolveFail(to, signature, reason, lowLevelData);
return false;
}
}
/**
* @dev evolve function for chip
*/
function evolveChip(
uint256[] memory ids,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external returns (bool success) {
address to = _msgSender();
try factory.evolveChip(to, ids, startTime, saltNonce, signature) {
return true;
} catch Error(string memory reason) {
bytes memory by;
factory.useSignature(signature);
emit TokenEvolveFail(to, signature, reason, by);
return false;
} catch (bytes memory lowLevelData) {
factory.useSignature(signature);
string memory reason;
emit TokenEvolveFail(to, signature, reason, lowLevelData);
return false;
}
}

View File

@ -28,6 +28,7 @@ contract UserMinterFactory is Ownable, FactoryBase, Initializable {
shard = IBEERC1155(addressArr[3]);
factory = MinterFactory(addressArr[4]);
}
/**
* @dev mint hero by user
*/
@ -36,32 +37,23 @@ contract UserMinterFactory is Ownable, FactoryBase, Initializable {
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external returns (bool success){
) external returns (bool success) {
address to = _msgSender();
try factory.mint721ByUser(to, tokenId, startTime, saltNonce, signature, hero) {
try
factory.mint721ByUser(to, tokenId, startTime, saltNonce, signature, hero)
{
return true;
} catch Error(string memory reason) {
bytes memory by;
factory.useSignature(signature);
emit TokenMintFail(
to,
signature,
reason,
by
);
emit TokenMintFail(to, signature, reason, by);
return false;
} catch (bytes memory lowLevelData) {
factory.useSignature(signature);
string memory reason;
emit TokenMintFail(
to,
signature,
reason,
lowLevelData
);
emit TokenMintFail(to, signature, reason, lowLevelData);
return false;
}
}
/**
@ -72,112 +64,104 @@ contract UserMinterFactory is Ownable, FactoryBase, Initializable {
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external returns (bool success){
) external returns (bool success) {
address to = _msgSender();
try factory.mint721ByUser(to, tokenId, startTime, saltNonce, signature, equip) {
try
factory.mint721ByUser(to, tokenId, startTime, saltNonce, signature, equip)
{
return true;
} catch Error(string memory reason) {
bytes memory by;
factory.useSignature(signature);
emit TokenMintFail(
to,
signature,
reason,
by
);
emit TokenMintFail(to, signature, reason, by);
return false;
} catch (bytes memory lowLevelData) {
factory.useSignature(signature);
string memory reason;
emit TokenMintFail(
to,
signature,
reason,
lowLevelData
);
emit TokenMintFail(to, signature, reason, lowLevelData);
return false;
}
}
/**
* @dev user batch mint 1155 chip
*/
* @dev user batch mint 1155 chip
*/
function mintChipBatchUser(
uint256[] memory ids,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external returns (bool success){
) external returns (bool success) {
uint256 len = ids.length;
uint256[] memory amounts = new uint256[](len);
for (uint256 i = 0; i < len; ++i) {
amounts[i] = 1;
}
address to = _msgSender();
try factory.mint1155BatchByUser(to, ids, amounts, startTime, saltNonce, signature, chip) {
try
factory.mint1155BatchByUser(
to,
ids,
amounts,
startTime,
saltNonce,
signature,
chip
)
{
return true;
} catch Error(string memory reason) {
} catch Error(string memory reason) {
bytes memory by;
factory.useSignature(signature);
emit TokenMintFail(
to,
signature,
reason,
by
);
emit TokenMintFail(to, signature, reason, by);
return false;
} catch (bytes memory lowLevelData) {
factory.useSignature(signature);
string memory reason;
emit TokenMintFail(
to,
signature,
reason,
lowLevelData
);
emit TokenMintFail(to, signature, reason, lowLevelData);
return false;
}
}
/**
* @dev user batch mint 1155 shard
*/
* @dev user batch mint 1155 shard
*/
function mintShardBatchUser(
uint256[] memory ids,
uint256[] memory amounts,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external returns (bool success){
) external returns (bool success) {
address to = _msgSender();
try factory.mint1155BatchByUser(to, ids, amounts, startTime, saltNonce, signature, shard) {
try
factory.mint1155BatchByUser(
to,
ids,
amounts,
startTime,
saltNonce,
signature,
shard
)
{
return true;
} catch Error(string memory reason) {
bytes memory by;
factory.useSignature(signature);
emit TokenMintFail(
to,
signature,
reason,
by
);
emit TokenMintFail(to, signature, reason, by);
return false;
} catch (bytes memory lowLevelData) {
factory.useSignature(signature);
string memory reason;
emit TokenMintFail(
to,
signature,
reason,
lowLevelData
);
emit TokenMintFail(to, signature, reason, lowLevelData);
return false;
}
}
/**
* @dev mint hero or equip with shard
*/
* @dev mint hero or equip with shard
*/
function shardMixByUser(
uint256 nftId,
uint8 nftType,
@ -197,36 +181,24 @@ contract UserMinterFactory is Ownable, FactoryBase, Initializable {
nft = equip;
}
ShardParam memory param = ShardParam(
to, nftId, payToken, payAmount, startTime, saltNonce);
try factory.shardMixByUser(
param,
ids,
amounts,
signature,
nft
) {
to,
nftId,
payToken,
payAmount,
startTime,
saltNonce
);
try factory.shardMixByUser(param, ids, amounts, signature, nft) {
return true;
} catch Error(string memory reason) {
bytes memory by;
factory.useSignature(signature);
emit TokenMintFail(
to,
signature,
reason,
by
);
emit TokenMintFail(to, signature, reason, by);
return false;
} catch (bytes memory lowLevelData) {
factory.useSignature(signature);
string memory reason;
emit TokenMintFail(
to,
signature,
reason,
lowLevelData
);
emit TokenMintFail(to, signature, reason, lowLevelData);
}
}
}
}

View File

@ -8,137 +8,150 @@ import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/governance/TimelockController.sol";
import "../core/HasSignature.sol";
contract BEBoxMall is Ownable, HasSignature, TimelockController{
using SafeERC20 for IERC20;
using Address for address;
contract BEBoxMall is Ownable, HasSignature, TimelockController {
using SafeERC20 for IERC20;
using Address for address;
uint256 public constant MIN_DELAY = 2 days;
uint256 public constant MAX_DELAY = 16 days;
uint256 private _minDelay;
uint256 public constant MIN_DELAY = 2 days;
uint256 public constant MAX_DELAY = 16 days;
uint256 private _minDelay;
bool public address_initialized;
bool public address_initialized;
constructor(
address[] memory proposers,
address[] memory executors)
TimelockController(MIN_DELAY, proposers, executors)
HasSignature("BEBoxMall", "1"){
_minDelay = MIN_DELAY;
address_initialized = false;
constructor(address[] memory proposers, address[] memory executors)
TimelockController(MIN_DELAY, proposers, executors)
HasSignature("BEBoxMall", "1")
{
_minDelay = MIN_DELAY;
address_initialized = false;
}
event BEBoxPaid(
uint256 indexed boxId,
address indexed buyer,
uint256 boxType,
uint256 price,
address paymentToken
);
address public paymentReceivedAddress;
function setPaymentReceivedAddress(address _paymentReceivedAddress) public {
require(
_paymentReceivedAddress != address(0),
"BEBoxMall::setPaymentReceivedAddress: payment received address can not be zero"
);
if (address_initialized) {
require(
msg.sender == address(this),
"BEBoxMall::setPaymentReceivedAddress: Call must come from BEBoxMall."
);
} else {
require(
msg.sender == owner(),
"BEBoxMall::setPaymentReceivedAddress: First call must come from owner."
);
address_initialized = true;
}
paymentReceivedAddress = _paymentReceivedAddress;
}
event BEBoxPaid(
uint256 indexed boxId,
address indexed buyer,
uint256 boxType,
uint256 price,
address paymentToken
/**
* @dev BE box payment function
*/
function payForBoxWithSignature(
uint256 boxId,
uint256 _type,
address userAddress,
uint256 price,
address paymentErc20,
uint256 saltNonce,
bytes calldata signature
) external onlyOwner signatureValid(signature) {
require(
!userAddress.isContract(),
"BEBoxPayment: Only user address is allowed to buy box"
);
require(_type > 0, "BEBoxPayment: Invalid box type");
require(price > 0, "BEBoxPayment: Invalid payment amount");
bytes32 criteriaMessageHash = getMessageHash(
_type,
paymentErc20,
price,
saltNonce
);
address public paymentReceivedAddress;
checkSigner712(userAddress, criteriaMessageHash, signature);
function setPaymentReceivedAddress(address _paymentReceivedAddress)
public
{
require(_paymentReceivedAddress != address(0), 'BEBoxMall::setPaymentReceivedAddress: payment received address can not be zero');
if (address_initialized) {
require(msg.sender == address(this), "BEBoxMall::setPaymentReceivedAddress: Call must come from BEBoxMall.");
} else {
require(msg.sender == owner(), "BEBoxMall::setPaymentReceivedAddress: First call must come from owner.");
address_initialized = true;
}
paymentReceivedAddress = _paymentReceivedAddress;
}
IERC20 paymentToken = IERC20(paymentErc20);
uint256 allowToPayAmount = paymentToken.allowance(
userAddress,
address(this)
);
require(allowToPayAmount >= price, "BEBoxPayment: Invalid token allowance");
// Transfer payment
paymentToken.safeTransferFrom(userAddress, paymentReceivedAddress, price);
useSignature(signature);
// Emit payment event
emit BEBoxPaid(boxId, userAddress, _type, price, paymentErc20);
}
/**
* @dev BE box payment function
*/
function payForBoxWithSignature(
uint256 boxId,
uint256 _type,
address userAddress,
uint256 price,
address paymentErc20,
uint256 saltNonce,
bytes calldata signature
) external onlyOwner signatureValid(signature){
require(
!userAddress.isContract(),
"BEBoxPayment: Only user address is allowed to buy box"
);
require(_type > 0, "BEBoxPayment: Invalid box type");
require(price > 0, "BEBoxPayment: Invalid payment amount");
bytes32 criteriaMessageHash = getMessageHash(
_type,
paymentErc20,
price,
saltNonce
);
function getMessageHash(
uint256 _boxType,
address _paymentErc20,
uint256 _price,
uint256 _saltNonce
) public pure returns (bytes32) {
return
keccak256(
abi.encode(
keccak256(
"set(uint256 item,address token,uint256 price,uint256 salt)"
),
_boxType,
_paymentErc20,
_price,
_saltNonce
)
);
}
checkSigner712(userAddress, criteriaMessageHash, signature);
/**
* @dev Returns the minimum delay for an operation to become valid.
*
* This value can be changed by executing an operation that calls `updateDelay`.
*/
function getMinDelay()
public
view
virtual
override
returns (uint256 duration)
{
return _minDelay;
}
IERC20 paymentToken = IERC20(paymentErc20);
uint256 allowToPayAmount = paymentToken.allowance(
userAddress,
address(this)
);
require(
allowToPayAmount >= price,
"BEBoxPayment: Invalid token allowance"
);
// Transfer payment
paymentToken.safeTransferFrom(
userAddress,
paymentReceivedAddress,
price
);
useSignature(signature);
// Emit payment event
emit BEBoxPaid(boxId, userAddress, _type, price, paymentErc20);
}
function getMessageHash(
uint256 _boxType,
address _paymentErc20,
uint256 _price,
uint256 _saltNonce
) public pure returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("set(uint256 item,address token,uint256 price,uint256 salt)"),
_boxType,
_paymentErc20,
_price,
_saltNonce
)
);
}
/**
* @dev Returns the minimum delay for an operation to become valid.
*
* This value can be changed by executing an operation that calls `updateDelay`.
*/
function getMinDelay() public view virtual override returns (uint256 duration) {
return _minDelay;
}
/**
* @dev Changes the minimum timelock duration for future operations.
*
* Emits a {MinDelayChange} event.
*
* Requirements:
*
* - the caller must be the timelock itself. This can only be achieved by scheduling and later executing
* an operation where the timelock is the target and the data is the ABI-encoded call to this function.
*/
function updateDelay(uint256 newDelay) external virtual override {
require(msg.sender == address(this), "BEBoxMall: caller must be timelock");
require(newDelay >= MIN_DELAY, "BEBoxMall: newDelay must greater than or equal to MIN_DELAY");
require(newDelay <= MAX_DELAY, "BEBoxMall: newDelay must less than or equal to MAX_DELAY");
emit MinDelayChange(_minDelay, newDelay);
_minDelay = newDelay;
}
/**
* @dev Changes the minimum timelock duration for future operations.
*
* Emits a {MinDelayChange} event.
*
* Requirements:
*
* - the caller must be the timelock itself. This can only be achieved by scheduling and later executing
* an operation where the timelock is the target and the data is the ABI-encoded call to this function.
*/
function updateDelay(uint256 newDelay) external virtual override {
require(msg.sender == address(this), "BEBoxMall: caller must be timelock");
require(
newDelay >= MIN_DELAY,
"BEBoxMall: newDelay must greater than or equal to MIN_DELAY"
);
require(
newDelay <= MAX_DELAY,
"BEBoxMall: newDelay must less than or equal to MAX_DELAY"
);
emit MinDelayChange(_minDelay, newDelay);
_minDelay = newDelay;
}
}

View File

@ -13,191 +13,191 @@ import "../core/HasSignature.sol";
// this contract will transfer ownership to BETimelockController after deployed
// all onlyowner method would add timelock
contract MarketPlace is Ownable, HasSignature {
using SafeERC20 for IERC20;
using SafeMath for uint256;
using SafeERC20 for IERC20;
using SafeMath for uint256;
// Supported payment token WETH & list of authorized ERC20
mapping(address => bool) public paymentTokens;
mapping(bytes => bool) public usedSignatures;
// Supported payment token WETH & list of authorized ERC20
mapping(address => bool) public paymentTokens;
mapping(bytes => bool) public usedSignatures;
// Address to receive transaction fee
address public feeToAddress;
uint256 public transactionFee;
// Address to receive transaction fee
address public feeToAddress;
uint256 public transactionFee;
uint256 public constant MIN_TRANSACTION_FEE = 50;
uint256 public constant MAX_TRANSACTION_FEE = 1000;
uint256 public constant MIN_TRANSACTION_FEE = 50;
uint256 public constant MAX_TRANSACTION_FEE = 1000;
// Events
event MatchTransaction(
uint256 indexed tokenId,
address contractAddress,
uint256 price,
address paymentToken,
address seller,
address buyer,
uint256 fee
// Events
event MatchTransaction(
uint256 indexed tokenId,
address contractAddress,
uint256 price,
address paymentToken,
address seller,
address buyer,
uint256 fee
);
constructor() HasSignature("MarketPlace", "1") {}
function setFeeToAddress(address _feeToAddress) external onlyOwner {
require(
_feeToAddress != address(0),
"fee received address can not be zero"
);
feeToAddress = _feeToAddress;
}
function setTransactionFee(uint256 _transactionFee) external onlyOwner {
require(
_transactionFee >= MIN_TRANSACTION_FEE &&
_transactionFee <= MAX_TRANSACTION_FEE,
"Marketplace: _transactionFee must >= 50 and <= 1000"
);
transactionFee = _transactionFee;
}
function setPaymentTokens(address[] calldata _paymentTokens)
external
onlyOwner
{
for (uint256 i = 0; i < _paymentTokens.length; i++) {
if (paymentTokens[_paymentTokens[i]]) {
continue;
}
paymentTokens[_paymentTokens[i]] = true;
}
}
function removePaymentTokens(address[] calldata _removedPaymentTokens)
external
onlyOwner
{
for (uint256 i = 0; i < _removedPaymentTokens.length; i++) {
paymentTokens[_removedPaymentTokens[i]] = false;
}
}
function ignoreSignature(
address[2] calldata addresses,
uint256[3] calldata values,
bytes calldata signature
) external signatureValid(signature) {
bytes32 criteriaMessageHash = getMessageHash(
addresses[0],
values[0],
addresses[1],
values[1],
values[2]
);
constructor()
HasSignature("MarketPlace", "1"){
checkSigner(_msgSender(), criteriaMessageHash, signature);
useSignature(signature);
}
/**
* @dev Function matched transaction with user signatures
*/
function matchTransaction(
address[3] calldata addresses,
uint256[3] calldata values,
bytes calldata signature
) external signatureValid(signature) returns (bool) {
// address[3] [seller_address,nft_address,payment_token_address]
// uint256[3] [token_id,price,salt_nonce]
// bytes seller_signature
require(paymentTokens[addresses[2]], "Marketplace: invalid payment method");
bytes32 criteriaMessageHash = getMessageHash(
addresses[1],
values[0],
addresses[2],
values[1],
values[2]
);
checkSigner712(addresses[0], criteriaMessageHash, signature);
// check current ownership
IERC721 nft = IERC721(addresses[1]);
require(
nft.ownerOf(values[0]) == addresses[0],
"Marketplace: seller is not owner of this item now"
);
// Check payment approval and buyer balance
IERC20 paymentContract = IERC20(addresses[2]);
require(
paymentContract.balanceOf(_msgSender()) >= values[1],
"Marketplace: buyer doesn't have enough token to buy this item"
);
require(
paymentContract.allowance(_msgSender(), address(this)) >= values[1],
"Marketplace: buyer doesn't approve marketplace to spend payment amount"
);
// We divide by 10000 to support decimal value such as 4.25% => 425 / 10000
uint256 fee = transactionFee.mul(values[1]).div(10000);
uint256 payToSellerAmount = values[1].sub(fee);
// transfer money to seller
paymentContract.safeTransferFrom(
_msgSender(),
addresses[0],
payToSellerAmount
);
// transfer fee to address
if (fee > 0) {
paymentContract.safeTransferFrom(_msgSender(), feeToAddress, fee);
}
function setFeeToAddress(address _feeToAddress) external onlyOwner {
require(_feeToAddress != address(0), 'fee received address can not be zero');
feeToAddress = _feeToAddress;
}
// transfer item to buyer
nft.safeTransferFrom(addresses[0], _msgSender(), values[0]);
function setTransactionFee(uint256 _transactionFee) external onlyOwner {
require(
_transactionFee >= MIN_TRANSACTION_FEE && _transactionFee <= MAX_TRANSACTION_FEE,
"Marketplace: _transactionFee must >= 50 and <= 1000"
);
transactionFee = _transactionFee;
}
useSignature(signature);
// emit sale event
emitEvent(addresses, values);
return true;
}
function setPaymentTokens(address[] calldata _paymentTokens)
external
onlyOwner
{
for (uint256 i = 0; i < _paymentTokens.length; i++) {
if (paymentTokens[_paymentTokens[i]]) {
continue;
}
/**
* @dev Function to emit transaction matched event
*/
function emitEvent(address[3] calldata addresses, uint256[3] calldata values)
internal
{
emit MatchTransaction(
values[0],
addresses[1],
values[1],
addresses[2],
addresses[0],
_msgSender(),
transactionFee
);
}
paymentTokens[_paymentTokens[i]] = true;
}
}
function removePaymentTokens(address[] calldata _removedPaymentTokens)
external
onlyOwner
{
for (uint256 i = 0; i < _removedPaymentTokens.length; i++) {
paymentTokens[_removedPaymentTokens[i]] = false;
}
}
function ignoreSignature(
address[2] calldata addresses,
uint256[3] calldata values,
bytes calldata signature
) external signatureValid(signature){
bytes32 criteriaMessageHash = getMessageHash(
addresses[0],
values[0],
addresses[1],
values[1],
values[2]
);
checkSigner(_msgSender(), criteriaMessageHash, signature);
useSignature(signature);
}
/**
* @dev Function matched transaction with user signatures
*/
function matchTransaction(
address[3] calldata addresses,
uint256[3] calldata values,
bytes calldata signature
) external signatureValid(signature) returns (bool) {
// address[3] [seller_address,nft_address,payment_token_address]
// uint256[3] [token_id,price,salt_nonce]
// bytes seller_signature
require(
paymentTokens[addresses[2]],
"Marketplace: invalid payment method"
);
bytes32 criteriaMessageHash = getMessageHash(
addresses[1],
values[0],
addresses[2],
values[1],
values[2]
);
checkSigner712(addresses[0], criteriaMessageHash, signature);
// check current ownership
IERC721 nft = IERC721(addresses[1]);
require(
nft.ownerOf(values[0]) == addresses[0],
"Marketplace: seller is not owner of this item now"
);
// Check payment approval and buyer balance
IERC20 paymentContract = IERC20(addresses[2]);
require(
paymentContract.balanceOf(_msgSender()) >= values[1],
"Marketplace: buyer doesn't have enough token to buy this item"
);
require(
paymentContract.allowance(_msgSender(), address(this)) >= values[1],
"Marketplace: buyer doesn't approve marketplace to spend payment amount"
);
// We divide by 10000 to support decimal value such as 4.25% => 425 / 10000
uint256 fee = transactionFee.mul(values[1]).div(10000);
uint256 payToSellerAmount = values[1].sub(fee);
// transfer money to seller
paymentContract.safeTransferFrom(
_msgSender(),
addresses[0],
payToSellerAmount
);
// transfer fee to address
if (fee > 0) {
paymentContract.safeTransferFrom(_msgSender(), feeToAddress, fee);
}
// transfer item to buyer
nft.safeTransferFrom(addresses[0], _msgSender(), values[0]);
useSignature(signature);
// emit sale event
emitEvent(addresses, values);
return true;
}
/**
* @dev Function to emit transaction matched event
*/
function emitEvent(
address[3] calldata addresses,
uint256[3] calldata values
) internal {
emit MatchTransaction(
values[0],
addresses[1],
values[1],
addresses[2],
addresses[0],
_msgSender(),
transactionFee
);
}
function getMessageHash(
address _nftAddress,
uint256 _tokenId,
address _paymentErc20,
uint256 _price,
uint256 _saltNonce
) public pure returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("set(address nft,uint256 tokenId,address payToken,uint256 price,uint256 salt)"),
_nftAddress,
_tokenId,
_paymentErc20,
_price,
_saltNonce
)
);
}
function getMessageHash(
address _nftAddress,
uint256 _tokenId,
address _paymentErc20,
uint256 _price,
uint256 _saltNonce
) public pure returns (bytes32) {
return
keccak256(
abi.encode(
keccak256(
"set(address nft,uint256 tokenId,address payToken,uint256 price,uint256 salt)"
),
_nftAddress,
_tokenId,
_paymentErc20,
_price,
_saltNonce
)
);
}
}

View File

@ -7,301 +7,285 @@ import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
abstract contract BEBase1155 is ERC1155, Ownable, AccessControl {
using Strings for uint256;
using Strings for uint256;
bytes32 public constant URI_SETTER_ROLE = keccak256("URI_SETTER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURN_ROLE = keccak256("BURN_ROLE");
bytes32 public constant LOCK_ROLE = keccak256("LOCK_ROLE");
bytes32 public constant URI_SETTER_ROLE = keccak256("URI_SETTER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURN_ROLE = keccak256("BURN_ROLE");
bytes32 public constant LOCK_ROLE = keccak256("LOCK_ROLE");
mapping(uint256 => bool) public lockedTokens;
mapping(uint256 => bool) public lockedTokens;
mapping(address => uint256[]) private _ownedTokens;
// for 0 means not exists, value stored = index + 1;
mapping(address => mapping(uint256 => uint256)) private _ownedTokensIndex;
mapping(address => uint256[]) private _ownedTokens;
// for 0 means not exists, value stored = index + 1;
mapping(address => mapping(uint256 => uint256)) private _ownedTokensIndex;
mapping(uint256 => uint256) private _totalSupply;
mapping(uint256 => uint256) private _totalSupply;
uint256 public maxSupply = 0;
uint256 public maxSupply = 0;
struct TokenStruct {
uint256 tokenId;
uint256 amount;
struct TokenStruct {
uint256 tokenId;
uint256 amount;
}
constructor() ERC1155("https://market.cebg.games/api/nft/info/{id}") {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(URI_SETTER_ROLE, msg.sender);
}
function setURI(string memory newuri) external onlyRole(URI_SETTER_ROLE) {
_setURI(newuri);
}
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) external onlyRole(MINTER_ROLE) {
_mintBatch(to, ids, amounts, data);
}
function burnBatch(
address account,
uint256[] memory ids,
uint256[] memory values
) external onlyRole(BURN_ROLE) {
_burnBatch(account, ids, values);
}
// The following functions are overrides required by Solidity.
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC1155, AccessControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
/**
* @dev Add factory to mint/burn item
*/
function setMintFactory(address factory) external onlyOwner {
_grantRole(MINTER_ROLE, factory);
}
/**
* @dev Remove factory
*/
function removeMintFactory(address factory) external onlyOwner {
_revokeRole(MINTER_ROLE, factory);
}
function grantLockRole(address account) external onlyOwner {
_grantRole(LOCK_ROLE, account);
}
function revokeLockRole(address account) external onlyOwner {
_revokeRole(LOCK_ROLE, account);
}
/**
* @dev Add factory to burn item
*/
function grantBurnRole(address proxy) external onlyOwner {
_grantRole(BURN_ROLE, proxy);
}
/**
* @dev Remove proxy
*/
function revokeBurnRole(address proxy) external onlyOwner {
_revokeRole(BURN_ROLE, proxy);
}
/**
* @dev Total amount of tokens in with a given id.
*/
function totalSupply(uint256 id) external view virtual returns (uint256) {
return _totalSupply[id];
}
/**
* @dev Indicates whether any token exist with a given id, or not.
*/
function exists(uint256 id) public view virtual returns (bool) {
return _totalSupply[id] > 0;
}
function canMint(
uint256 /*id*/
) external view virtual returns (bool) {
return true;
}
/**
* @dev Lock token to use in game or for rental
*/
function lock(uint256 id) external onlyRole(LOCK_ROLE) {
require(_totalSupply[id] > 0, "Must be valid tokenId");
require(!lockedTokens[id], "Token has already locked");
lockedTokens[id] = true;
}
function lockBatch(uint256[] memory ids) external onlyRole(LOCK_ROLE) {
uint256 len = ids.length;
for (uint256 i = 0; i < len; ++i) {
uint256 id = ids[i];
require(_totalSupply[id] > 0, "Must be valid tokenId");
require(!lockedTokens[id], "Token has already locked");
lockedTokens[id] = true;
}
}
constructor() ERC1155("https://market.cebg.games/api/nft/info/{id}") {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(URI_SETTER_ROLE, msg.sender);
/**
* @dev Unlock token to use blockchain or sale on marketplace
*/
function unlock(uint256 id) external onlyRole(LOCK_ROLE) {
require(_totalSupply[id] > 0, "Must be valid tokenId");
require(lockedTokens[id], "Token has already unlocked");
lockedTokens[id] = false;
}
function unlockBatch(uint256[] memory ids) external onlyRole(LOCK_ROLE) {
uint256 len = ids.length;
for (uint256 i = 0; i < len; ++i) {
uint256 id = ids[i];
require(_totalSupply[id] > 0, "Must be valid tokenId");
require(lockedTokens[id], "Token has already unlocked");
lockedTokens[id] = false;
}
}
function setURI(string memory newuri) external onlyRole(URI_SETTER_ROLE) {
_setURI(newuri);
/**
* @dev Get lock status
*/
function isLocked(uint256 id) external view returns (bool) {
return lockedTokens[id];
}
function isLockedBatch(uint256[] memory ids)
external
view
returns (bool[] memory)
{
uint256 len = ids.length;
bool[] memory results = new bool[](len);
for (uint256 i = 0; i < len; ++i) {
results[i] = lockedTokens[ids[i]];
}
return results;
}
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) external onlyRole(MINTER_ROLE) {
_mintBatch(to, ids, amounts, data);
/**
* @dev See {ERC1155-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
uint256 len = ids.length;
for (uint256 i = 0; i < len; ++i) {
require(!lockedTokens[ids[i]], "Can not transfer locked token");
}
function burnBatch(
address account,
uint256[] memory ids,
uint256[] memory values
) external onlyRole(BURN_ROLE) {
_burnBatch(account, ids, values);
}
// The following functions are overrides required by Solidity.
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC1155, AccessControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
/**
* @dev Add factory to mint/burn item
*/
function setMintFactory(address factory)
external
onlyOwner
{
_grantRole(MINTER_ROLE, factory);
}
/**
* @dev Remove factory
*/
function removeMintFactory(address factory)
external
onlyOwner
{
_revokeRole(MINTER_ROLE, factory);
}
function grantLockRole(address account)
external
onlyOwner
{
_grantRole(LOCK_ROLE, account);
}
function revokeLockRole(address account)
external
onlyOwner
{
_revokeRole(LOCK_ROLE, account);
}
/**
* @dev Add factory to burn item
*/
function grantBurnRole(address proxy) external onlyOwner {
_grantRole(BURN_ROLE, proxy);
}
/**
* @dev Remove proxy
*/
function revokeBurnRole(address proxy) external onlyOwner {
_revokeRole(BURN_ROLE, proxy);
}
/**
* @dev Total amount of tokens in with a given id.
*/
function totalSupply(uint256 id) external view virtual returns (uint256) {
return _totalSupply[id];
}
/**
* @dev Indicates whether any token exist with a given id, or not.
*/
function exists(uint256 id) public view virtual returns (bool) {
return _totalSupply[id] > 0;
}
function canMint(uint256 /*id*/) external view virtual returns (bool) {
return true;
}
/**
* @dev Lock token to use in game or for rental
*/
function lock(uint256 id) external onlyRole(LOCK_ROLE) {
require(_totalSupply[id] > 0, "Must be valid tokenId");
require(!lockedTokens[id], "Token has already locked");
lockedTokens[id] = true;
}
function lockBatch(uint256[] memory ids) external onlyRole(LOCK_ROLE) {
uint256 len = ids.length;
for (uint256 i = 0; i < len; ++i) {
uint256 id = ids[i];
require(_totalSupply[id] > 0, "Must be valid tokenId");
require(!lockedTokens[id], "Token has already locked");
lockedTokens[id] = true;
if (from == address(0)) {
// mint nft
for (uint256 i = 0; i < len; ++i) {
_totalSupply[ids[i]] += amounts[i];
if (maxSupply > 0) {
require(
_totalSupply[ids[i]] <= maxSupply,
"Can not mint for exceeds max supply"
);
}
}
} else if (from != to) {
// transfer from -> to
for (uint256 i = 0; i < len; ++i) {
_removeTokenFromOwnerEnumeration(from, ids[i], amounts[i]);
}
}
/**
* @dev Unlock token to use blockchain or sale on marketplace
*/
function unlock(uint256 id) external onlyRole(LOCK_ROLE) {
require(_totalSupply[id] > 0, "Must be valid tokenId");
require(lockedTokens[id], "Token has already unlocked");
lockedTokens[id] = false;
if (to == address(0)) {
// burn nft
for (uint256 i = 0; i < len; ++i) {
_totalSupply[ids[i]] -= amounts[i];
}
} else if (to != from) {
// mint or transfer from -> to
for (uint256 i = 0; i < len; ++i) {
_addTokenToOwnerEnumeration(to, ids[i]);
}
}
}
function unlockBatch(uint256[] memory ids) external onlyRole(LOCK_ROLE) {
uint256 len = ids.length;
for (uint256 i = 0; i < len; ++i) {
uint256 id = ids[i];
require(_totalSupply[id] > 0, "Must be valid tokenId");
require(lockedTokens[id], "Token has already unlocked");
lockedTokens[id] = false;
}
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
if (_ownedTokensIndex[to][tokenId] == 0 && balanceOf(to, tokenId) == 0) {
_ownedTokensIndex[to][tokenId] = _ownedTokens[to].length + 1;
_ownedTokens[to].push(tokenId);
}
}
/**
* @dev Get lock status
*/
function isLocked(uint256 id) external view returns (bool) {
return lockedTokens[id];
function _removeTokenFromOwnerEnumeration(
address from,
uint256 tokenId,
uint256 amount
) private {
uint256 balance = balanceOf(from, tokenId);
if (balance == amount) {
uint256 lastTokenIndex = _ownedTokens[from].length - 1;
uint256 tokenIndex = _ownedTokensIndex[from][tokenId] - 1;
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
// Move the last token to the slot of the to-delete token
_ownedTokens[from][tokenIndex] = lastTokenId;
// Update the moved token's index
_ownedTokensIndex[from][lastTokenId] = tokenIndex + 1;
// This also deletes the contents at the last position of the array
delete _ownedTokensIndex[from][tokenId];
_ownedTokens[from].pop();
}
}
function isLockedBatch(uint256[] memory ids)
external
view
returns (bool[] memory)
{
uint256 len = ids.length;
bool[] memory results = new bool[](len);
for (uint256 i = 0; i < len; ++i) {
results[i] = lockedTokens[ids[i]];
}
return results;
function userTokens(
address user,
uint256 start,
uint256 page
) external view returns (TokenStruct[] memory) {
uint256 size = _ownedTokens[user].length;
uint256 max = size;
uint256 pageSize = 0;
if (start < size) {
if (start + page < size) {
pageSize = page;
max = start + page;
} else {
pageSize = size - start;
}
}
/**
* @dev See {ERC1155-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
uint256 len = ids.length;
for (uint256 i = 0; i < len; ++i) {
require(!lockedTokens[ids[i]], "Can not transfer locked token");
}
if (from == address(0)) {
// mint nft
for (uint256 i = 0; i < len; ++i) {
_totalSupply[ids[i]] += amounts[i];
if (maxSupply > 0) {
require(
_totalSupply[ids[i]] <= maxSupply,
"Can not mint for exceeds max supply"
);
}
}
} else if (from != to) {
// transfer from -> to
for (uint256 i = 0; i < len; ++i) {
_removeTokenFromOwnerEnumeration(from, ids[i], amounts[i]);
}
}
if (to == address(0)) {
// burn nft
for (uint256 i = 0; i < len; ++i) {
_totalSupply[ids[i]] -= amounts[i];
}
} else if (to != from) {
// mint or transfer from -> to
for (uint256 i = 0; i < len; ++i) {
_addTokenToOwnerEnumeration(to, ids[i]);
}
}
}
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
if (
_ownedTokensIndex[to][tokenId] == 0 && balanceOf(to, tokenId) == 0
) {
_ownedTokensIndex[to][tokenId] = _ownedTokens[to].length + 1;
_ownedTokens[to].push(tokenId);
}
TokenStruct[] memory results = new TokenStruct[](pageSize);
if (pageSize > 0) {
for (uint256 i = start; i < max; ++i) {
TokenStruct memory dataObj;
uint256 tokenId = _ownedTokens[user][i];
dataObj.tokenId = tokenId;
dataObj.amount = balanceOf(user, tokenId);
results[i - start] = dataObj;
}
}
return results;
}
function _removeTokenFromOwnerEnumeration(
address from,
uint256 tokenId,
uint256 amount
) private {
uint256 balance = balanceOf(from, tokenId);
if (balance == amount) {
uint256 lastTokenIndex = _ownedTokens[from].length - 1;
uint256 tokenIndex = _ownedTokensIndex[from][tokenId] - 1;
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
// Move the last token to the slot of the to-delete token
_ownedTokens[from][tokenIndex] = lastTokenId;
// Update the moved token's index
_ownedTokensIndex[from][lastTokenId] = tokenIndex + 1;
// This also deletes the contents at the last position of the array
delete _ownedTokensIndex[from][tokenId];
_ownedTokens[from].pop();
}
}
function userTokens(
address user,
uint256 start,
uint256 page
) external view returns (TokenStruct[] memory) {
uint256 size = _ownedTokens[user].length;
uint256 max = size;
uint256 pageSize = 0;
if (start < size) {
if (start + page < size) {
pageSize = page;
max = start + page;
} else {
pageSize = size - start;
}
}
TokenStruct[] memory results = new TokenStruct[](pageSize);
if (pageSize > 0) {
for (uint256 i = start; i < max; ++i) {
TokenStruct memory dataObj;
uint256 tokenId = _ownedTokens[user][i];
dataObj.tokenId = tokenId;
dataObj.amount = balanceOf(user, tokenId);
results[i - start] = dataObj;
}
}
return results;
}
function tokenTypes(address user) external view returns (uint256) {
return _ownedTokens[user].length;
}
function tokenTypes(address user) external view returns (uint256) {
return _ownedTokens[user].length;
}
}

View File

@ -4,13 +4,13 @@ pragma solidity 0.8.10;
import "./BEBase1155.sol";
contract BEChip1155 is BEBase1155 {
mapping(uint256 => uint256) public tokenLevels;
mapping(uint256 => uint256) public tokenLevels;
constructor() {
maxSupply = 1;
}
constructor() {
maxSupply = 1;
}
function canMint(uint256 id) external view override returns (bool) {
return !exists(id);
}
function canMint(uint256 id) external view override returns (bool) {
return !exists(id);
}
}

View File

@ -2,9 +2,10 @@
pragma solidity 0.8.10;
import "./BEBase1155.sol";
/**
* for Hero and Weapon shard
*/
contract BEShard is BEBase1155 {
}

View File

@ -2,11 +2,10 @@
pragma solidity 0.8.10;
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
contract BECoin is ERC20Burnable {
uint256 public constant INITIALIZED_CAP = 100000000 * 1e18;
uint256 public constant INITIALIZED_CAP = 100000000 * 1e18;
constructor() ERC20("CRYPTO ELITE'S COIN", "CEC") {
_mint(_msgSender(), INITIALIZED_CAP);
}
}
constructor() ERC20("CRYPTO ELITE'S COIN", "CEC") {
_mint(_msgSender(), INITIALIZED_CAP);
}
}

View File

@ -4,33 +4,31 @@ 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/Ownable.sol";
/**
* this contract will transfer ownership to BETimelockController after deployed
* all onlyowner method would add timelock
*/
contract BEGold is ERC20, ERC20Burnable, Pausable, Ownable {
constructor() ERC20("CRYPTO ELITE'S GOLD", "CEG") {}
function pause() external onlyOwner {
_pause();
}
constructor() ERC20("CRYPTO ELITE'S GOLD", "CEG") {
}
function unpause() external onlyOwner {
_unpause();
}
function pause() external onlyOwner {
_pause();
}
function mint(address to, uint256 amount) external onlyOwner {
_mint(to, amount);
}
function unpause() external onlyOwner {
_unpause();
}
function mint(address to, uint256 amount) external onlyOwner {
_mint(to, amount);
}
function _beforeTokenTransfer(address from, address to, uint256 amount)
internal
whenNotPaused
override
{
super._beforeTokenTransfer(from, to, amount);
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal override whenNotPaused {
super._beforeTokenTransfer(from, to, amount);
}
}

View File

@ -7,164 +7,157 @@ import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
abstract contract BEBase is ERC721, AccessControl, ERC721Enumerable, Ownable {
using Strings for uint256;
using Strings for uint256;
mapping(uint256 => bool) public lockedTokens;
string private _baseTokenURI = "https://market.cebg.games/api/nft/info/";
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURN_ROLE = keccak256("BURN_ROLE");
bytes32 public constant LOCK_ROLE = keccak256("LOCK_ROLE");
mapping(uint256 => bool) public lockedTokens;
string private _baseTokenURI = "https://market.cebg.games/api/nft/info/";
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURN_ROLE = keccak256("BURN_ROLE");
bytes32 public constant LOCK_ROLE = keccak256("LOCK_ROLE");
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
/**
* @dev Creates a new token for `to`. Its token ID will be automatically
* assigned (and available on the emitted {IERC721-Transfer} event), and the token
* URI autogenerated based on the base URI passed at construction.
*
* See {ERC721-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(address to, uint256 tokenId)
external
onlyRole(MINTER_ROLE)
virtual {
require(!_exists(tokenId), "Must have unique tokenId");
// We cannot just use balanceOf to create the new tokenId because tokens
// can be burned (destroyed), so we need a separate counter.
_mint(to, tokenId);
}
/**
* @dev Creates a new token for `to`. Its token ID will be automatically
* assigned (and available on the emitted {IERC721-Transfer} event), and the token
* URI autogenerated based on the base URI passed at construction.
*
* See {ERC721-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(address to, uint256 tokenId)
external
virtual
onlyRole(MINTER_ROLE)
{
require(!_exists(tokenId), "Must have unique tokenId");
// We cannot just use balanceOf to create the new tokenId because tokens
// can be burned (destroyed), so we need a separate counter.
_mint(to, tokenId);
}
/**
* @dev Add factory to mint item
*/
function setMintFactory(address factory) external onlyOwner {
_grantRole(MINTER_ROLE, factory);
}
/**
* @dev Add factory to mint item
*/
function setMintFactory(address factory) external onlyOwner {
_grantRole(MINTER_ROLE, factory);
}
/**
* @dev Remove factory
*/
function removeMintFactory(address factory) external onlyOwner {
_revokeRole(MINTER_ROLE, factory);
}
/**
* @dev Remove factory
*/
function removeMintFactory(address factory) external onlyOwner {
_revokeRole(MINTER_ROLE, factory);
}
/**
* @dev Add factory to burn item
*/
function grantBurnRole(address proxy) external onlyOwner {
_grantRole(BURN_ROLE, proxy);
}
/**
* @dev Add factory to burn item
*/
function grantBurnRole(address proxy) external onlyOwner {
_grantRole(BURN_ROLE, proxy);
}
/**
* @dev Remove proxy
*/
function revokeBurnProxy(address proxy) external onlyOwner {
_revokeRole(BURN_ROLE, proxy);
}
/**
* @dev Add address to lock item
*/
function grantLockRole(address account)
external
onlyOwner
{
_grantRole(LOCK_ROLE, account);
}
/**
* @dev Remove address for lock item
*/
function revokeLockRole(address account)
external
onlyOwner
{
_revokeRole(LOCK_ROLE, account);
}
/**
* @dev Remove proxy
*/
function revokeBurnProxy(address proxy) external onlyOwner {
_revokeRole(BURN_ROLE, proxy);
}
/**
* @dev Add address to lock item
*/
function grantLockRole(address account) external onlyOwner {
_grantRole(LOCK_ROLE, account);
}
/**
* @dev Lock token to use in game or for rental
*/
function lock(uint256 tokenId) external onlyRole(LOCK_ROLE) {
require(_exists(tokenId), "Must be valid tokenId");
require(!lockedTokens[tokenId], "Token has already locked");
lockedTokens[tokenId] = true;
}
/**
* @dev Remove address for lock item
*/
function revokeLockRole(address account) external onlyOwner {
_revokeRole(LOCK_ROLE, account);
}
/**
* @dev Unlock token to use blockchain or sale on marketplace
*/
function unlock(uint256 tokenId) external onlyRole(LOCK_ROLE){
require(_exists(tokenId), "Must be valid tokenId");
require(lockedTokens[tokenId], "Token has already unlocked");
lockedTokens[tokenId] = false;
}
/**
* @dev Lock token to use in game or for rental
*/
function lock(uint256 tokenId) external onlyRole(LOCK_ROLE) {
require(_exists(tokenId), "Must be valid tokenId");
require(!lockedTokens[tokenId], "Token has already locked");
lockedTokens[tokenId] = true;
}
/**
* @dev Get lock status
*/
function isLocked(uint256 tokenId) external view returns (bool) {
return lockedTokens[tokenId];
}
/**
* @dev Unlock token to use blockchain or sale on marketplace
*/
function unlock(uint256 tokenId) external onlyRole(LOCK_ROLE) {
require(_exists(tokenId), "Must be valid tokenId");
require(lockedTokens[tokenId], "Token has already unlocked");
lockedTokens[tokenId] = false;
}
/**
* @dev Set token URI
*/
function updateBaseURI(string calldata baseTokenURI) external onlyOwner {
_baseTokenURI = baseTokenURI;
}
/**
* @dev Get lock status
*/
function isLocked(uint256 tokenId) external view returns (bool) {
return lockedTokens[tokenId];
}
/**
* @dev See {IERC165-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override(ERC721, ERC721Enumerable) {
require(!lockedTokens[tokenId], "Can not transfer locked token");
super._beforeTokenTransfer(from, to, tokenId);
}
/**
* @dev Set token URI
*/
function updateBaseURI(string calldata baseTokenURI) external onlyOwner {
_baseTokenURI = baseTokenURI;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(AccessControl, ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC165-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override(ERC721, ERC721Enumerable) {
require(!lockedTokens[tokenId], "Can not transfer locked token");
super._beforeTokenTransfer(from, to, tokenId);
}
/**
* @dev Burns `tokenId`.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function burn(address owner, uint256 tokenId)
external
onlyRole(BURN_ROLE)
virtual
{
require(_exists(tokenId), "TokenId not exists");
require(!lockedTokens[tokenId], "Can not burn locked token");
require(
ownerOf(tokenId) == owner,
"current address is not owner of this item now"
);
_burn(tokenId);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(AccessControl, ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
/**
* @dev Burns `tokenId`.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function burn(address owner, uint256 tokenId)
external
virtual
onlyRole(BURN_ROLE)
{
require(_exists(tokenId), "TokenId not exists");
require(!lockedTokens[tokenId], "Can not burn locked token");
require(
ownerOf(tokenId) == owner,
"current address is not owner of this item now"
);
_burn(tokenId);
}
}

View File

@ -4,6 +4,6 @@ import "./BEBase.sol";
// this contract will transfer ownership to BETimelockController after deployed
// all onlyowner method would add timelock
contract BEChip is BEBase{
constructor() ERC721("CRYPTO ELITE'S CHIP", "CHIP") {}
contract BEChip is BEBase {
constructor() ERC721("CRYPTO ELITE'S CHIP", "CHIP") {}
}

View File

@ -4,6 +4,6 @@ import "./BEBase.sol";
// this contract will transfer ownership to BETimelockController after deployed
// all onlyowner method would add timelock
contract BEEquipment is BEBase{
constructor() ERC721("CRYPTO ELITE'S WEAPON", "WEAPON") {}
contract BEEquipment is BEBase {
constructor() ERC721("CRYPTO ELITE'S WEAPON", "WEAPON") {}
}

View File

@ -4,6 +4,6 @@ import "./BEBase.sol";
// this contract will transfer ownership to BETimelockController after deployed
// all onlyowner method would add timelock
contract BEHero is BEBase{
constructor() ERC721("CRYPTO ELITE'S HERO", "HERO") {}
}
contract BEHero is BEBase {
constructor() ERC721("CRYPTO ELITE'S HERO", "HERO") {}
}

View File

@ -4,23 +4,26 @@ import "./BEBase.sol";
// this contract will transfer ownership to BETimelockController after deployed
// all onlyowner method would add timelock
contract BEMysteryBox is BEBase{
constructor() ERC721("CRYPTO ELITE'S MYSTERY BOXES", "BOX") {}
function userTokens(address user, uint256 start, uint256 page)
external view returns (uint256 [] memory){
uint256 size = balanceOf(user);
uint256[] memory results = new uint256[](page);
if (start < size) {
uint256 max = size;
if (start + page < size) {
max = start + page;
}
for (uint256 i = start; i < max; ++i) {
uint256 tokenId = tokenOfOwnerByIndex(user, i);
results[i-start] = tokenId;
}
}
return results;
contract BEMysteryBox is BEBase {
constructor() ERC721("CRYPTO ELITE'S MYSTERY BOXES", "BOX") {}
function userTokens(
address user,
uint256 start,
uint256 page
) external view returns (uint256[] memory) {
uint256 size = balanceOf(user);
uint256[] memory results = new uint256[](page);
if (start < size) {
uint256 max = size;
if (start + page < size) {
max = start + page;
}
for (uint256 i = start; i < max; ++i) {
uint256 tokenId = tokenOfOwnerByIndex(user, i);
results[i - start] = tokenId;
}
}
return results;
}
}

View File

@ -5,13 +5,14 @@ import "@openzeppelin/contracts/access/Ownable.sol";
contract TimeChecker is Ownable {
mapping(address => bool) private approvalLists;
uint256 private _duration;
constructor() {
_duration = 1 days;
}
modifier timeValid(uint256 time) {
require(
time + _duration >= block.timestamp,
time + _duration >= block.timestamp,
"expired, please send another transaction with new signature"
);
_;
@ -20,10 +21,9 @@ contract TimeChecker is Ownable {
/**
* @dev Returns the max duration for function called by user
*/
function getDuration() external view
returns (uint256 duration) {
return _duration;
}
function getDuration() external view returns (uint256 duration) {
return _duration;
}
/**
* @dev Change duration value
@ -31,6 +31,4 @@ contract TimeChecker is Ownable {
function updateDuation(uint256 valNew) external onlyOwner {
_duration = valNew;
}
}

View File

@ -1,9 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
library UInt{
function asSingletonArray(uint256 element) internal pure returns (uint256[] memory) {
library UInt {
function asSingletonArray(uint256 element)
internal
pure
returns (uint256[] memory)
{
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;

104
package-lock.json generated
View File

@ -1426,6 +1426,15 @@
"integrity": "sha1-n7OjzzEyMoFR81PeRjLgHlIQK+o=",
"dev": true
},
"@solidity-parser/parser": {
"version": "0.14.3",
"resolved": "https://registry.npmmirror.com/@solidity-parser/parser/-/parser-0.14.3.tgz",
"integrity": "sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==",
"dev": true,
"requires": {
"antlr4ts": "^0.5.0-alpha.4"
}
},
"@szmarczak/http-timer": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/@szmarczak/http-timer/download/@szmarczak/http-timer-1.1.2.tgz",
@ -3061,6 +3070,12 @@
"color-convert": "^1.9.0"
}
},
"antlr4ts": {
"version": "0.5.0-alpha.4",
"resolved": "https://registry.npmmirror.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz",
"integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==",
"dev": true
},
"any-signal": {
"version": "2.1.2",
"resolved": "https://registry.npmmirror.com/any-signal/download/any-signal-2.1.2.tgz",
@ -15296,6 +15311,89 @@
"dev": true,
"optional": true
},
"prettier": {
"version": "2.7.1",
"resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.7.1.tgz",
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
"dev": true
},
"prettier-plugin-solidity": {
"version": "1.0.0-beta.24",
"resolved": "https://registry.npmmirror.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.24.tgz",
"integrity": "sha512-6JlV5BBTWzmDSq4kZ9PTXc3eLOX7DF5HpbqmmaF+kloyUwOZbJ12hIYsUaZh2fVgZdV2t0vWcvY6qhILhlzgqg==",
"dev": true,
"requires": {
"@solidity-parser/parser": "^0.14.3",
"emoji-regex": "^10.1.0",
"escape-string-regexp": "^4.0.0",
"semver": "^7.3.7",
"solidity-comments-extractor": "^0.0.7",
"string-width": "^4.2.3"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true
},
"emoji-regex": {
"version": "10.1.0",
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-10.1.0.tgz",
"integrity": "sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==",
"dev": true
},
"escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"semver": {
"version": "7.3.7",
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"dependencies": {
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
}
}
},
"strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.1"
}
}
}
},
"printj": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/printj/download/printj-1.1.2.tgz",
@ -16708,6 +16806,12 @@
}
}
},
"solidity-comments-extractor": {
"version": "0.0.7",
"resolved": "https://registry.npmmirror.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz",
"integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==",
"dev": true
},
"source-list-map": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/source-list-map/download/source-list-map-2.0.1.tgz",

View File

@ -6,6 +6,8 @@
"scripts": {
"test": "npx truffle test",
"build": "truffle compile",
"prettier": "prettier --write 'contracts/**/*.sol'",
"lint": "prettier --list-different 'contracts/**/*.sol'",
"deploy:dev": "truffle migrate --network development",
"deploy:20": "truffle migrate --network lan20 --compile-none",
"deploy:22": "truffle migrate --network lan22 --compile-none",
@ -20,6 +22,8 @@
"@openzeppelin/test-helpers": "^0.5.15",
"@truffle/hdwallet-provider": "^2.0.0",
"chai": "^4.3.4",
"prettier": "^2.7.1",
"prettier-plugin-solidity": "^1.0.0-beta.24",
"truffle": "^5.4.23",
"truffle-plugin-stdjsonin": "git+https://github.com/mhrsalehi/truffle-plugin-stdjsonin.git",
"truffle-plugin-verify": "^0.5.25"