becrypto/contracts/logic/BEShardFactory.sol
2022-08-10 11:49:51 +08:00

82 lines
2.6 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import "../interfaces/IBEERC1155.sol";
import "../interfaces/IBEERC721.sol";
import "../core/HasSignature.sol";
contract BEShardFactory is Ownable, Initializable, HasSignature {
address public executor;
IBEERC1155 public shard;
IBEERC721 public hero;
IBEERC721 public weapon;
mapping(bytes => bool) public usedSignatures;
constructor() HasSignature("BEShardFactory", "1") {}
event ShardMinted(
address contractAddress,
address indexed to,
uint256[] ids
);
function init(address[3] calldata nfts) external initializer onlyOwner {
shard = IBEERC1155(nfts[0]);
hero = IBEERC721(nfts[1]);
weapon = IBEERC721(nfts[2]);
}
/**
* @dev update executor
*/
function updateExecutor(address account) external onlyOwner {
require(account != address(0), "address can not be zero");
executor = account;
}
function mintShardBatch(
uint256[] memory ids,
uint256[] memory amounts,
uint256 saltNonce,
bytes calldata signature
) external {
uint256 len = ids.length;
require(len > 0, "BEShardFactory: ids cannot be empty");
require(
len == amounts.length,
"BEShardFactory: ids and amounts length mismatch"
);
require(
!usedSignatures[signature],
"BEShardFactory:: mintShardBatch: signature used. please send another transaction with new signature"
);
address to = _msgSender();
uint256[] memory signArray = new uint256[](len * 2);
for (uint256 i = 0; i < len; ++i) {
signArray[i * 2] = ids[i];
signArray[i * 2 + 1] = amounts[i];
}
bytes32 criteriaMessageHash = getMessageHash(to, saltNonce, signArray);
checkSigner(executor, criteriaMessageHash, signature);
shard.mintBatch(to, ids, amounts, "");
usedSignatures[signature] = true;
emit ShardMinted(address(shard), to, ids);
}
function getMessageHash(
address _to,
uint256 _saltNonce,
uint256[] memory _ids
) public pure returns (bytes32) {
bytes memory encoded = abi.encodePacked(_to, _saltNonce);
uint256 len = _ids.length;
for (uint256 i = 0; i < len; ++i) {
encoded = bytes.concat(encoded, abi.encodePacked(_ids[i]));
}
return keccak256(encoded);
}
}