96 lines
2.8 KiB
Solidity
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);
|
|
}
|
|
|
|
}
|