增加luckybox相关合约

This commit is contained in:
cebgcontract 2022-04-18 17:23:42 +08:00
parent 2b336a24bc
commit b3e843dfc1
19 changed files with 59320 additions and 42809 deletions

File diff suppressed because one or more lines are too long

View File

@ -24405,8 +24405,8 @@
}
},
"links": {},
"address": "0xfE44E188e7B802FfA2CA9Cd75e254AA9737661e8",
"transactionHash": "0x05e54135f100fb5ae2ee07237eb8b6da6cef645f2e904d191c889046cdc3f567"
"address": "0x28429230DB35B90222d4D3D93C355e647b173F0D",
"transactionHash": "0xcf40c64980ec719910670f3d48cf6507f645babc7b4cc2b056a7d8725cedda6a"
},
"1644989050832": {
"events": {
@ -24586,7 +24586,7 @@
}
},
"schemaVersion": "3.4.3",
"updatedAt": "2022-04-17T04:30:42.742Z",
"updatedAt": "2022-04-18T08:52:27.900Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -9935,8 +9935,8 @@
}
},
"links": {},
"address": "0xb13D4bD423ED5154fDE47a6F95Ea32Dd013d3Ee6",
"transactionHash": "0x9557eb1dc71d6e704caada3923ab05af5d9195ff10e148c9dd99cbc7e11093d8"
"address": "0x7be62476BC4610678242837B4174791b528252dF",
"transactionHash": "0xe6bb997bf8b9b0bdc6fc72076928eadf70a999824c9682015a75c2c57affc1a4"
},
"1644989050832": {
"events": {},
@ -9946,7 +9946,7 @@
}
},
"schemaVersion": "3.4.3",
"updatedAt": "2022-04-17T04:30:42.756Z",
"updatedAt": "2022-04-18T08:52:27.847Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -24405,8 +24405,8 @@
}
},
"links": {},
"address": "0x238c4D4BC1dc273f68229aeC966c5a4B90d586Ae",
"transactionHash": "0xe4d2f23a969175bf7465536f20ac0d1e133289e9941a35ed63e6f71cff1e41f9"
"address": "0x8395d60CAb914BeA3cf31d7Ca089648CE43C01Fc",
"transactionHash": "0x72c44a98afd8f1b4acc497d2334f140906a1744577fa8af45c050444b46dd81b"
},
"1644989050832": {
"events": {
@ -24586,7 +24586,7 @@
}
},
"schemaVersion": "3.4.3",
"updatedAt": "2022-04-17T04:30:42.721Z",
"updatedAt": "2022-04-18T08:52:27.883Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -13372,12 +13372,12 @@
}
},
"links": {},
"address": "0x8bCD46D7EBBb6b1986c0e09137C8935A49D333F4",
"transactionHash": "0x8016a3f827b7d2950c1458aea93c6973a84cbd76eeb578f523c35ffff9fb43a2"
"address": "0xDa1d417C0E1f2804e4B1F23bbc579351B3A57aD2",
"transactionHash": "0x098f0b21615cadd4fd0f32104059e6dac0407f267f7cc9df08bd10c5028c0a53"
}
},
"schemaVersion": "3.4.3",
"updatedAt": "2022-04-17T04:30:42.766Z",
"updatedAt": "2022-04-18T08:52:27.855Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -24411,8 +24411,8 @@
}
},
"links": {},
"address": "0x67C4A3dc635F1F77484d979a0231199f4daEEDCD",
"transactionHash": "0xa84bd4cff67c1c418bdbc43abcb1288a3ba9a28191f8255f56da3b2b3805c4d3"
"address": "0x5C5d3733E121f4c80Cc2d54656FdeC92886524eA",
"transactionHash": "0xe61aa40601fa70a1b56357cc83caae559af46a6ee107a2381e18743639cacaa1"
},
"1644989050832": {
"events": {
@ -24592,7 +24592,7 @@
}
},
"schemaVersion": "3.4.3",
"updatedAt": "2022-04-17T04:30:42.703Z",
"updatedAt": "2022-04-18T08:52:27.867Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

File diff suppressed because one or more lines are too long

View File

@ -24642,8 +24642,8 @@
}
},
"links": {},
"address": "0xBC4e9B0f3C1B31c55D2D4761bAdFc82Dc0aa192e",
"transactionHash": "0x77ca6712f1a08950847d3454e43ee686b5e7a73ddf761fa6e2982bec780771dc"
"address": "0x4E4A2A099d2650A7aF9DE5d2da87D6d79e93Fa05",
"transactionHash": "0x63b66afd9722cccb8e09d31d38ed5fec9b2392dda3c110fc995872711df34dc0"
},
"1644989050832": {
"events": {},
@ -24652,8 +24652,8 @@
"transactionHash": "0xc13387ad01f45d9a7c045af16a6eeb7fec49afd74e749083a8545329c3b8845b"
}
},
"schemaVersion": "3.4.4",
"updatedAt": "2022-04-17T01:05:39.745Z",
"schemaVersion": "3.4.3",
"updatedAt": "2022-04-18T08:52:27.800Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -27667,8 +27667,8 @@
}
},
"links": {},
"address": "0x78904cA8e87213810228bF5fb328b0764f0Bd057",
"transactionHash": "0x5537229dbfb33d2eecad62ce680aa7bbaab22707b54a5618072f5827b7ae62f7"
"address": "0x54b32776809F83f75A29c0be1267e367015b128b",
"transactionHash": "0xed9d7f87663ad6ae51789c7b613f23c689a8d33f57f5582faad01f858acd131c"
},
"1644989050832": {
"events": {},
@ -27678,7 +27678,7 @@
}
},
"schemaVersion": "3.4.3",
"updatedAt": "2022-04-17T04:30:42.653Z",
"updatedAt": "2022-04-18T08:52:27.944Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -33792,8 +33792,8 @@
}
},
"links": {},
"address": "0xe39F132c311E4D95DEE93F3103D70AcEf7d23530",
"transactionHash": "0x1c2bcee486cdfaec58827f1628981e6114fa10cd684503ab271a1b0faa164b95"
"address": "0x04ca99f41A68cb318fb2342b34B0FbF28581b7cc",
"transactionHash": "0x06acd237f37236e834ed967f6af3b7c01a493d51480565bb522346bb3faa812c"
},
"1644989050832": {
"events": {
@ -33872,7 +33872,7 @@
}
},
"schemaVersion": "3.4.3",
"updatedAt": "2022-04-17T04:30:42.619Z",
"updatedAt": "2022-04-18T08:52:27.919Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -3164,8 +3164,8 @@
"1338": {
"events": {},
"links": {},
"address": "0x6e0C31F3b2c076eA1B67dac75789E7117163569c",
"transactionHash": "0xe03a76f8796f8ff7feee3d6b25c156acc633bfeec1ddcd4c268173113211d877"
"address": "0x576Ed6FE49C5fcA2E6A618ddBccb8f97b7E010cf",
"transactionHash": "0xe68e61fd451b9c4fdcdd4b1698154601121f42d4fa2ae13aed133fe0aadd402e"
},
"1644989050832": {
"events": {},
@ -3175,7 +3175,7 @@
}
},
"schemaVersion": "3.4.3",
"updatedAt": "2022-04-17T04:30:42.771Z",
"updatedAt": "2022-04-18T08:52:28.002Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -8961,8 +8961,8 @@
}
},
"links": {},
"address": "0x03B154bC82853fA963AC31754c4D76841EE0fDFB",
"transactionHash": "0x08ccc35d11a2edb2410bbf17c408218c8b1b93d89ad9de8463ba628b3ff1433b"
"address": "0x675539743AAbd2eF5771191Ed5094b6bE0709ccD",
"transactionHash": "0x6a4a7da384337306413f7d14ac7a0a2cb0fc50f8535c4a6fe837c5d8125cfc25"
},
"1644989050832": {
"events": {},
@ -8972,7 +8972,7 @@
}
},
"schemaVersion": "3.4.3",
"updatedAt": "2022-04-17T04:30:42.639Z",
"updatedAt": "2022-04-18T08:52:27.934Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -10,6 +10,16 @@ contract BELuckyBox is ERC1155, AccessControl {
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);
@ -76,4 +86,105 @@ contract BELuckyBox is ERC1155, AccessControl {
_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

@ -8,8 +8,18 @@ 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;
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 {
@ -22,6 +32,11 @@ contract LuckyBoxProxy is Ownable, Initializable, HasSignature {
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;
@ -36,15 +51,18 @@ contract LuckyBoxProxy is Ownable, Initializable, HasSignature {
event BoxOpened(
address indexed to,
uint256 indexed boxId,
uint256[] ids,
uint256[] types
uint256 val,
uint256[3] ids,
uint8[3] types
);
constructor()
HasSignature("LuckyBoxProxy", "1"){
}
constructor() HasSignature("LuckyBoxProxy", "1") {}
function init(address _erc1155, address[3] calldata _erc721s) external initializer onlyOwner {
function init(address _erc1155, address[3] calldata _erc721s)
external
initializer
onlyOwner
{
box = IMintableERC1155(_erc1155);
hero = IMintableERC721(_erc721s[0]);
equip = IMintableERC721(_erc721s[1]);
@ -55,12 +73,16 @@ contract LuckyBoxProxy is Ownable, Initializable, HasSignature {
* @dev update executor
*/
function updateExecutor(address account) external onlyOwner {
require(account != address(0), 'address can not be zero');
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');
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);
}
@ -68,63 +90,61 @@ contract LuckyBoxProxy is Ownable, Initializable, HasSignature {
function openBox(
uint256 boxId,
uint256[3] memory ids,
uint256[3] memory types,
uint256 saltNonce,
bytes calldata signature
) external {
require(ids.length == types.length, "LuckyBoxProxy: ids and types length mismatch");
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],
types[0],
types[1],
types[2],
saltNonce
);
checkSigner(executor, criteriaMessageHash, signature);
usedSignatures[signature] = true;
address owner = msg.sender;
// open box
box.burn(owner, boxId, 1);
// random count
uint256 val = rand(owner, saltNonce, 100);
// mint nft
uint256[] memory results;
uint256[] memory resultTypes;
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];
resultTypes[0] = types[0];
if (val > 80) {
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];
resultTypes[1] = types[1];
}
if (val > 90) {
} 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];
resultTypes[2] = types[2];
}
emit BoxOpened(
owner,
boxId,
results,
resultTypes
);
emit BoxOpened(owner, boxId, val, results, types);
}
function mint721WithType(address to, uint256 tokenId, uint256 typeNum) private {
if (typeNum == 0) {
function mint721WithType(
address to,
uint256 tokenId,
uint256 typeNum
) private {
if (typeNum == 1) {
hero.mint(to, tokenId);
} else if (typeNum == 1) {
} else if (typeNum == 2) {
equip.mint(to, tokenId);
} else {
} else if (typeNum == 3) {
chip.mint(to, tokenId);
}
}
@ -133,9 +153,18 @@ contract LuckyBoxProxy is Ownable, Initializable, HasSignature {
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;
) internal view returns (uint256) {
uint256 random = uint256(
keccak256(
abi.encodePacked(
owner,
nonce,
block.difficulty,
block.timestamp
)
)
);
return random % _length;
}
function getMessageHash(
@ -143,9 +172,6 @@ contract LuckyBoxProxy is Ownable, Initializable, HasSignature {
uint256 _firstToken,
uint256 _secondToken,
uint256 _thirdToken,
uint256 _type1,
uint256 _type2,
uint256 _type3,
uint256 _saltNonce
) public pure returns (bytes32) {
return
@ -155,9 +181,6 @@ contract LuckyBoxProxy is Ownable, Initializable, HasSignature {
_firstToken,
_secondToken,
_thirdToken,
_type1,
_type2,
_type3,
_saltNonce
)
);

View File

@ -34,7 +34,7 @@ module.exports = async function (deployer, network, accounts) {
chipInstance.address
]
)
await boxProxyInstance.updateExecutor('0x834c5C0EC1D94584026fC419E29e89A4D040605a');
await heroInstance.setMintFactory(boxProxyInstance.address);
await equipInstance.setMintFactory(boxProxyInstance.address);
await chipInstance.setMintFactory(boxProxyInstance.address);

View File

@ -52,7 +52,7 @@ module.exports = async function (deployer, network, accounts) {
jsons.push({name: 'timelock', json: 'assets/contracts/BETimelockController.json', address: timelockInstance.address})
jsons.push({name: 'luckbox', json: 'assets/contracts/BELuckyBox.json', address: luckyBoxInstance.address})
jsons.push({name: 'boxproxy', json: 'assets/contracts/LuckyBoxProxy.json', address: boxProxyInstance.address})
console.log(jsons);
console.log(JSON.stringify(jsons));
console.log(`export const userAddress = '${accounts[0]}';`)
console.log(`export const privateKey = '';`)
console.log(`export const userBuyAddress = '${accounts[1]}';`)