// 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); } }