becrypto/contracts/logic/ShardAssembler.sol

96 lines
2.8 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../interfaces/IBEERC1155.sol";
import "../interfaces/IAsset.sol";
import "../core/HasSignature.sol";
import "../utils/TimeChecker.sol";
import "../market/MallBase.sol";
import "../utils/UInt.sol";
contract ShardAssembler is Ownable, TimeChecker, HasSignature, MallBase {
using SafeERC20 for IERC20;
using UInt for uint256;
IAsset public hero;
IBEERC1155 public shard;
struct AssembleParams {
uint256 tokenId;
address payToken;
uint256 tokenAmount;
uint256 startTime;
uint256 saltNonce;
}
event ShardAssembled(
address indexed to,
uint256 indexed tokenId,
address indexed payToken,
uint256 tokenAmount
);
// generate constructor
constructor(address[2] memory _addresses){
hero = IAsset(_addresses[0]);
shard = IBEERC1155(_addresses[1]);
}
function assembleShard(
AssembleParams calldata params,
uint256[] memory ids,
uint256[] memory amounts,
bytes calldata signature
) external signatureValid(signature) timeValid(params.startTime) {
require(ids.length > 0, "ShardAssembler: ids length must > 0");
require(params.tokenId > 0, "ShardAssembler: tokenId can not be 0");
require(erc20Supported[params.payToken], "ShardAssembler: payToken not supported");
address user = _msgSender();
uint256[] memory signArray = new uint256[](ids.length * 2);
for (uint256 i = 0; i < ids.length; ++i) {
signArray[i * 2] = ids[i];
signArray[i * 2 + 1] = amounts[i];
}
bytes32 criteriaMessageHash =
getMessageHash(params, user, address(hero), address(this), signArray);
checkSigner(executor, criteriaMessageHash, signature);
shard.burnBatch(user, ids, amounts);
hero.batchMint(user, params.tokenId.asSingletonArray());
_useSignature(signature);
// transfer token to this contract
IERC20(params.payToken).transferFrom(user, feeToAddress, params.tokenAmount);
emit ShardAssembled(user, params.tokenId, params.payToken, params.tokenAmount);
}
function getMessageHash(
AssembleParams memory params,
address user,
address nftAddress,
address contractAddress,
uint256[] memory _ids
) internal pure returns (bytes32) {
bytes memory encoded = abi.encodePacked(
user,
nftAddress,
contractAddress,
params.tokenId,
params.payToken,
params.tokenAmount,
params.startTime,
params.saltNonce
);
uint256 len = _ids.length;
for (uint256 i = 0; i < len; ++i) {
encoded = bytes.concat(encoded, abi.encodePacked(_ids[i]));
}
return keccak256(encoded);
}
}