调整目录结构

This commit is contained in:
cebgcontract 2022-08-10 11:49:51 +08:00
parent 40208a9e00
commit 77b2a1934e
22 changed files with 7 additions and 385 deletions

View File

@ -5,7 +5,7 @@ import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import "../interfaces/IBEERC1155.sol";
import "../interfaces/IBEERC721.sol";
import "../HasSignature.sol";
import "../core/HasSignature.sol";
contract BEChipFactory is Ownable, Initializable, HasSignature {
IBEERC1155 public chip;

View File

@ -5,7 +5,7 @@ import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import "../interfaces/IBEERC1155.sol";
import "../interfaces/IBEERC721.sol";
import "../HasSignature.sol";
import "../core/HasSignature.sol";
contract BEShardFactory is Ownable, Initializable, HasSignature {
address public executor;

View File

@ -3,7 +3,7 @@ pragma solidity 0.8.10;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./HasSignature.sol";
import "../core/HasSignature.sol";
// this contract will transfer ownership to BETimelockController after deployed
// all onlyowner method would add timelock

View File

@ -4,7 +4,7 @@ pragma solidity 0.8.10;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "../HasSignature.sol";
import "../core/HasSignature.sol";
interface IMintableERC721 is IERC721 {
function mint(address to, uint256 tokenId) external;

View File

@ -4,7 +4,7 @@ pragma solidity 0.8.10;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "../HasSignature.sol";
import "../core/HasSignature.sol";
interface IMintableERC721 is IERC721 {
function mint(address to, uint256 tokenId) external;

View File

@ -6,7 +6,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/governance/TimelockController.sol";
import "./HasSignature.sol";
import "../core/HasSignature.sol";
contract BEBoxMall is Ownable, HasSignature, TimelockController{
using SafeERC20 for IERC20;

View File

@ -8,7 +8,7 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "./HasSignature.sol";
import "../core/HasSignature.sol";
// this contract will transfer ownership to BETimelockController after deployed
// all onlyowner method would add timelock

View File

@ -1,190 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
contract BELuckyBox is ERC1155, AccessControl {
bytes32 public constant URI_SETTER_ROLE = keccak256("URI_SETTER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURN_ROLE = keccak256("BURN_ROLE");
struct TokenStruct {
uint256 tokenId;
uint256 amount;
}
mapping(address => uint256[]) private _ownedTokens;
mapping(address => mapping(uint256 => uint256)) private _ownedTokensIndex;
mapping(uint256 => uint256) private _totalSupply;
constructor() ERC1155("https://market.cebg.games/api/nft/info/{id}") {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(URI_SETTER_ROLE, msg.sender);
}
function setURI(string memory newuri) external onlyRole(URI_SETTER_ROLE) {
_setURI(newuri);
}
function mint(address account, uint256 id, uint256 amount, bytes memory data)
external
onlyRole(MINTER_ROLE)
{
_mint(account, id, amount, data);
}
function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
external
onlyRole(MINTER_ROLE)
{
_mintBatch(to, ids, amounts, data);
}
function burn(
address account,
uint256 id,
uint256 value
) external onlyRole(BURN_ROLE) {
_burn(account, id, value);
}
function burnBatch(
address account,
uint256[] memory ids,
uint256[] memory values
) external onlyRole(BURN_ROLE) {
_burnBatch(account, ids, values);
}
// The following functions are overrides required by Solidity.
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC1155, AccessControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
/**
* @dev Add factory to mint/burn item
*/
function setMintFactory(address factory) external onlyRole(DEFAULT_ADMIN_ROLE) {
_grantRole(MINTER_ROLE, factory);
_grantRole(BURN_ROLE, factory);
}
/**
* @dev Remove factory
*/
function removeMintFactory(address factory) external onlyRole(DEFAULT_ADMIN_ROLE) {
_revokeRole(MINTER_ROLE, factory);
_revokeRole(BURN_ROLE, factory);
}
/**
* @dev Total amount of tokens in with a given id.
*/
function totalSupply(uint256 id) public view virtual returns (uint256) {
return _totalSupply[id];
}
/**
* @dev Indicates whether any token exist with a given id, or not.
*/
function exists(uint256 id) public view virtual returns (bool) {
return BELuckyBox.totalSupply(id) > 0;
}
/**
* @dev See {ERC1155-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
if (from == address(0)) {
// mint nft
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] += amounts[i];
}
} else if (from != to){
// transfer from -> to
for (uint256 i = 0; i < ids.length; ++i) {
_removeTokenFromOwnerEnumeration(from, ids[i], amounts[i]);
}
}
if (to == address(0)) {
// burn nft
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] -= amounts[i];
}
} else if (to != from) {
// mint or transfer from -> to
for (uint256 i = 0; i < ids.length; ++i) {
_addTokenToOwnerEnumeration(to, ids[i]);
}
}
}
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
if (_ownedTokensIndex[to][tokenId] == 0 && balanceOf(to, tokenId) == 0) {
_ownedTokensIndex[to][tokenId] = _ownedTokens[to].length;
_ownedTokens[to].push(tokenId);
}
}
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId, uint256 amount) private {
uint256 balance = balanceOf(from, tokenId);
if (balance == amount) {
uint256 lastTokenIndex = _ownedTokens[from].length - 1;
uint256 tokenIndex = _ownedTokensIndex[from][tokenId];
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[from][lastTokenId] = tokenIndex; // Update the moved token's index
// This also deletes the contents at the last position of the array
delete _ownedTokensIndex[from][tokenId];
_ownedTokens[from].pop();
}
}
function userTokens(address user, uint256 start, uint256 page)
external view returns (TokenStruct [] memory){
uint256 size = _ownedTokens[user].length;
TokenStruct[] memory results = new TokenStruct[](page);
if (start < size) {
uint256 max = size;
if (start + page < size) {
max = start + page;
}
for (uint256 i = start; i < max; ++i) {
TokenStruct memory dataObj;
uint256 tokenId = _ownedTokens[user][i];
dataObj.tokenId = tokenId;
dataObj.amount = balanceOf(user, tokenId);
results[i-start] = dataObj;
}
}
return results;
}
function tokenTypes(address user) external view returns (uint256) {
return _ownedTokens[user].length;
}
}

View File

@ -1,188 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "../HasSignature.sol";
interface IMintableERC1155 is IERC1155 {
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) external;
function burn(
address owner,
uint256 tokenId,
uint256 amount
) external;
}
interface IMintableERC721 is IERC721 {
function mint(address to, uint256 tokenId) external;
}
contract LuckyBoxProxy is Ownable, Initializable, HasSignature {
IMintableERC1155 public box;
IMintableERC721 public hero;
IMintableERC721 public equip;
IMintableERC721 public chip;
uint8 public constant TYPE_NONE = 0;
uint8 public constant TYPE_HERO = 1;
uint8 public constant TYPE_EQUIP = 2;
uint8 public constant TYPE_CHIP = 3;
address public executor;
mapping(bytes => bool) public usedSignatures;
event BoxMinted(
address contractAddress,
address indexed to,
uint256[] ids,
uint256[] amounts
);
event BoxOpened(
address indexed to,
uint256 indexed boxId,
uint256 val,
uint256[3] ids,
uint8[3] types
);
constructor() HasSignature("LuckyBoxProxy", "1") {}
function init(address _erc1155, address[3] calldata _erc721s)
external
initializer
onlyOwner
{
box = IMintableERC1155(_erc1155);
hero = IMintableERC721(_erc721s[0]);
equip = IMintableERC721(_erc721s[1]);
chip = IMintableERC721(_erc721s[2]);
}
/**
* @dev update executor
*/
function updateExecutor(address account) external onlyOwner {
require(account != address(0), "address can not be zero");
executor = account;
}
function mintBoxTo(
address to,
uint256[] memory ids,
uint256[] memory amounts
) external onlyOwner {
require(to != address(0), "to address can not be zero");
box.mintBatch(to, ids, amounts, "");
emit BoxMinted(address(box), to, ids, amounts);
}
function openBox(
uint256 boxId,
uint256[3] memory ids,
uint256 saltNonce,
bytes calldata signature
) external {
require(
!usedSignatures[signature],
"LuckyBoxProxy: signature used. please send another transaction with new signature"
);
address owner = msg.sender;
bytes32 criteriaMessageHash = getMessageHash(
boxId,
ids[0],
ids[1],
ids[2],
saltNonce
);
checkSigner(executor, criteriaMessageHash, signature);
usedSignatures[signature] = true;
// open box
box.burn(owner, boxId, 1);
uint256[3] memory results = [ids[0], 0, 0];
uint8[3] memory types = [TYPE_HERO, TYPE_NONE, TYPE_NONE];
mint721WithType(owner, ids[0], types[0]);
results[0] = ids[0];
uint256 val = rand(owner, saltNonce, 100);
if (val >= 70 && val < 90) {
types[1] = TYPE_CHIP;
mint721WithType(owner, ids[1], types[1]);
results[1] = ids[1];
} else if (val >= 90 && val < 98) {
types[1] = TYPE_EQUIP;
mint721WithType(owner, ids[1], types[1]);
results[1] = ids[1];
} else if (val >= 98) {
types[1] = TYPE_EQUIP;
mint721WithType(owner, ids[1], types[1]);
results[1] = ids[1];
types[2] = TYPE_CHIP;
mint721WithType(owner, ids[2], types[2]);
results[2] = ids[2];
}
emit BoxOpened(owner, boxId, val, results, types);
}
function mint721WithType(
address to,
uint256 tokenId,
uint256 typeNum
) private {
if (typeNum == 1) {
hero.mint(to, tokenId);
} else if (typeNum == 2) {
equip.mint(to, tokenId);
} else if (typeNum == 3) {
chip.mint(to, tokenId);
}
}
function rand(
address owner,
uint256 nonce,
uint256 _length
) internal view returns (uint256) {
uint256 random = uint256(
keccak256(
abi.encodePacked(
owner,
nonce,
block.difficulty,
block.timestamp
)
)
);
return random % _length;
}
function getMessageHash(
uint256 _boxId,
uint256 _firstToken,
uint256 _secondToken,
uint256 _thirdToken,
uint256 _saltNonce
) public pure returns (bytes32) {
return
keccak256(
abi.encodePacked(
_boxId,
_firstToken,
_secondToken,
_thirdToken,
_saltNonce
)
);
}
}