增加芯片升级逻辑

This commit is contained in:
cebgcontract 2022-08-17 11:45:47 +08:00
parent 86e5ec2531
commit defedda2e9
6 changed files with 260 additions and 104 deletions

View File

@ -17,5 +17,7 @@ interface IBEERC1155 is IERC1155 {
uint256[] memory values
) external;
function balanceOf(address account, uint256 id) external view returns (uint256);
function canMint(uint256 id) external view returns (bool);
}

View File

@ -8,4 +8,5 @@ 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);
}

View File

@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "../interfaces/IBEERC721.sol";
import "../interfaces/IBEERC1155.sol";
interface IEvolveFactory {
function evolve721NFT(
address to,
uint256[3] calldata tokenIds,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature,
IBEERC721 nft
) external;
function evolveChip(
address to,
uint256[] memory tokenIds,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external;
function useSignature(
bytes calldata signature
) external;
}

View File

@ -13,110 +13,134 @@ import "../core/HasSignature.sol";
// all onlyowner method would add timelock
contract EvolveFactory is Ownable, TimeChecker, Initializable, HasSignature {
using UInt for uint256;
IBEERC721 public hero;
IBEERC721 public equip;
IBEERC1155 public chip;
uint256 private _duration;
using UInt for uint256;
IBEERC721 public hero;
IBEERC721 public equip;
IBEERC1155 public chip;
address public executor;
address public executor;
event TokenEvolved(
address indexed owner,
uint256[3] tokenIds
event TokenEvolved(
address indexed owner,
uint256[] tokenIds
);
constructor()
HasSignature("EvolveFactory", "1"){
}
function init(address[3] calldata _erc721s) external initializer onlyOwner {
hero = IBEERC721(_erc721s[0]);
equip = IBEERC721(_erc721s[1]);
chip = IBEERC1155(_erc721s[2]);
}
/**
* @dev update executor
*/
function updateExecutor(address account) external onlyOwner {
require(account != address(0), 'address can not be zero');
executor = account;
}
function evolve721NFT(
address to,
uint256[3] calldata tokenIds,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature,
IBEERC721 nft
) external signatureValid(signature) timeValid(startTime){
require(
tokenIds[0] > 0 && tokenIds[1] > 0,
"EvolveFactory: token to evolve and burn can not be 0"
);
constructor()
HasSignature("EvolveFactory", "1"){
require(
tokenIds[0] != tokenIds[1],
"EvolveFactory: token to evolve and burn can not be same"
);
require(
nft.ownerOf(tokenIds[0]) == to && nft.ownerOf(tokenIds[1]) == to,
"EvolveFactory: current address is not owner of this nft now"
);
if (tokenIds[2] > 0) {
require(
chip.balanceOf(to, tokenIds[2]) > 0,
"EvolveFactory: not enough chip"
);
}
function init(address[3] calldata _erc721s) external initializer onlyOwner {
hero = IBEERC721(_erc721s[0]);
equip = IBEERC721(_erc721s[1]);
chip = IBEERC1155(_erc721s[2]);
uint256[] memory signArray = new uint256[](3);
for (uint256 i = 0; i < tokenIds.length; ++ i) {
uint256 _id = tokenIds[i];
signArray[i] = _id;
}
/**
* @dev update executor
*/
function updateExecutor(address account) external onlyOwner {
require(account != address(0), 'address can not be zero');
executor = account;
bytes32 criteriaMessageHash = getMessageHash(
to,
startTime,
saltNonce,
signArray
);
checkSigner(executor, criteriaMessageHash, signature);
nft.burn(to, tokenIds[1]);
if (tokenIds[2] > 0) {
uint256 amount = 1;
chip.burnBatch(to,
tokenIds[2].asSingletonArray(),
amount.asSingletonArray());
}
useSignature(signature);
emit TokenEvolved(
to,
signArray
);
}
function evolve721NFT(
address to,
uint256[3] calldata tokenIds,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature,
IBEERC721 nft
) internal signatureValid(signature) timeValid(startTime){
require(
tokenIds[0] > 0 && tokenIds[1] > 0,
"EvolveFactory: equip to evolve and burn can not be 0"
);
require(
tokenIds[0] != tokenIds[1],
"EvolveFactory: equip to evolve and burn can not be same"
);
require(
nft.ownerOf(tokenIds[0]) == to,
"EvolveFactory: current address is not owner of this nft now"
);
require(
nft.ownerOf(tokenIds[1]) == to,
"EvolveFactory: current address is not owner of this nft now"
);
if (tokenIds[2] > 0) {
require(
nft.ownerOf(tokenIds[2]) == to,
"EvolveFactory: current address is not owner of this nft now"
);
}
uint256[] memory signArray = new uint256[](3);
for (uint256 i = 0; i < tokenIds.length; ++ i) {
signArray[i] = tokenIds[i];
}
bytes32 criteriaMessageHash = getMessageHash(
to,
startTime,
saltNonce,
signArray
);
checkSigner(executor, criteriaMessageHash, signature);
nft.burn(to, tokenIds[1]);
if (tokenIds[2] > 0) {
uint256 amount = 1;
chip.burnBatch(to,
tokenIds[2].asSingletonArray(),
amount.asSingletonArray());
}
useSignature(signature);
emit TokenEvolved(
to,
tokenIds
);
function evolveChip(
address to,
uint256[] memory tokenIds,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) 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 idsForBurn = new uint256[](len - 1);
for (uint256 i = 0; i < len; ++ i) {
require(
chip.balanceOf(to, tokenIds[i]) > 0,
"EvolveFacrory: Chip specified not exists"
);
if (i > 0) {
idsForBurn[i - 1] = tokenIds[i];
amounts[i - 1] = 1;
}
}
bytes32 criteriaMessageHash = getMessageHash(to, startTime, saltNonce, tokenIds);
checkSigner(executor, criteriaMessageHash, signature);
chip.burnBatch(to, idsForBurn, amounts);
useSignature(signature);
emit TokenEvolved(
to,
tokenIds
);
}
function getMessageHash(
address _to,
uint256 _startTime,
uint256 _saltNonce,
uint256[] memory _ids
) public pure returns (bytes32) {
bytes memory encoded = abi.encodePacked(_to, _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 getMessageHash(
address _to,
uint256 _startTime,
uint256 _saltNonce,
uint256[] memory _ids
) public pure returns (bytes32) {
bytes memory encoded = abi.encodePacked(_to, _startTime, _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

@ -2,47 +2,138 @@
pragma solidity 0.8.10;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import "../interfaces/INFTFactory.sol";
import "../interfaces/IEvolveFactory.sol";
import "../interfaces/IBEERC721.sol";
import "../interfaces/IBEERC1155.sol";
contract UserEvolveFactory is Ownable, Initializable {
IEvolveFactory factory;
IBEERC721 public hero;
IBEERC721 public equip;
IBEERC1155 public chip;
IBEERC1155 public shard;
event TokenEvolveFail (
address indexed to,
uint256 mainToken,
bytes signature,
string reason,
bytes byteReason
);
function init() external initializer onlyOwner {
function init(address[3] calldata _nfts) external initializer onlyOwner {
hero = IBEERC721(_nfts[0]);
equip = IBEERC721(_nfts[1]);
chip = IBEERC1155(_nfts[2]);
}
/**
* @dev evolve function to Blissful Elites Hero NFT
* @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 {
) external returns (bool success){
address to = _msgSender();
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
);
return false;
} catch (bytes memory lowLevelData) {
factory.useSignature(signature);
string memory reason;
emit TokenEvolveFail(
to,
signature,
reason,
lowLevelData
);
return false;
}
}
/**
* @dev evolve function to Blissful Elites Equip NFT
* @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{
) 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
);
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

@ -174,7 +174,18 @@ contract UserMinterFactory is Ownable, Initializable {
);
return false;
}
}
/**
* @dev mint hero or equip with shard
*/
function shardMixByUser(
uint256[] memory ids,
uint256[] memory amounts,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external returns (bool success) {
return true;
}
}