add nft chip locker

This commit is contained in:
cebgcontract 2022-11-04 13:50:24 +08:00
parent 2504b02211
commit 76c300f97f
32 changed files with 89812 additions and 62344 deletions

File diff suppressed because one or more lines are too long

View File

@ -45792,8 +45792,8 @@
}
},
"links": {},
"address": "0x13A1D278e74bd7d0d206Bfa6F360eb2D9F451c3B",
"transactionHash": "0x9f35fbe58822dad4c8edc47b9a947b1b860f824cd94649c1ca626d1f5a8a4b48"
"address": "0xfd87166Aa4BF51275581C9a6817B3Bc33d866945",
"transactionHash": "0x3f90d7505677537d2e5ba51579aa35cc1e069403e4c96c1182c18f1c96f5221a"
},
"80001": {
"events": {},
@ -45881,7 +45881,7 @@
}
},
"schemaVersion": "3.4.9",
"updatedAt": "2022-11-03T08:04:09.215Z",
"updatedAt": "2022-11-04T05:16:38.421Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

File diff suppressed because one or more lines are too long

View File

@ -29441,8 +29441,8 @@
}
},
"links": {},
"address": "0x04874BF9a4fb5fE83f3770b64FB0E7771584343A",
"transactionHash": "0x68fee97de5519932ee62c38ad7c97542fd4cddf70802c03d3998ef62e3bc325e"
"address": "0x0DB84570A89A95d91eB331f8248fEeba8491cd04",
"transactionHash": "0xf7ec51fb65e5568a849910818d1c8b670f43671b1a0ab3d200df88c4b1a3ff36"
},
"80001": {
"events": {},
@ -29530,7 +29530,7 @@
}
},
"schemaVersion": "3.4.9",
"updatedAt": "2022-11-03T08:03:48.321Z",
"updatedAt": "2022-11-04T05:16:21.137Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -9689,8 +9689,8 @@
}
},
"links": {},
"address": "0xfBD1e45815c07EfaD2EF6FA445984C2dFa50d554",
"transactionHash": "0x376009c449f0dfe8fd59b340e0dd20e469e6126fbd41417244056f176fca5c3b"
"address": "0xDb1DAdccA7acC905AF7F3336828C36c85dc0f39b",
"transactionHash": "0x5de79a4fd75c91986d2eca8128d3dc48c95752c3004ae60517edbf8aae91e89f"
},
"80001": {
"events": {},
@ -9778,7 +9778,7 @@
}
},
"schemaVersion": "3.4.9",
"updatedAt": "2022-11-03T08:03:34.376Z",
"updatedAt": "2022-11-04T05:16:06.439Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

File diff suppressed because one or more lines are too long

View File

@ -11782,8 +11782,8 @@
}
},
"links": {},
"address": "0xDD407CE1bCAD846bC2f0e9D05c5ED1Dee6f6485b",
"transactionHash": "0xcb8f643cd07308b71229a5a43aabeb6b9d8a32446a6e40a92630f2fcfe35bcc1"
"address": "0x3a936D6Ec8e28f7254A1603D33d040eE044a8340",
"transactionHash": "0x03bb0b0e3284429e1f258025b310079f74d79c88415185d7ac41403f0e6e27b9"
},
"80001": {
"events": {},
@ -11871,7 +11871,7 @@
}
},
"schemaVersion": "3.4.9",
"updatedAt": "2022-11-03T08:03:37.906Z",
"updatedAt": "2022-11-04T05:16:10.362Z",
"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

File diff suppressed because one or more lines are too long

View File

@ -28836,8 +28836,8 @@
}
},
"links": {},
"address": "0x57E1B587B11D0170c351322862F20406B965D95d",
"transactionHash": "0xa2e17cf6d074b102840c5be48a4c7ef7c9ac60b474c00f5b4798cef2f76911d7"
"address": "0x419974f76Ab611FC370477F8a5e9bE19eaB89Ec4",
"transactionHash": "0x70d97fb45d1b250c5a836ab59ec79cd874bbeb7aaa5590164364f140a53e6cfc"
},
"80001": {
"events": {},
@ -28925,7 +28925,7 @@
}
},
"schemaVersion": "3.4.9",
"updatedAt": "2022-11-03T08:03:53.690Z",
"updatedAt": "2022-11-04T05:16:24.950Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -25354,8 +25354,8 @@
}
},
"links": {},
"address": "0xa97323430aC136DbD786316Ad1e3ee230862c7C9",
"transactionHash": "0x0b546c28b14da80144b18a6d1d937950e2fc2070c24b282193c4638282d8b183"
"address": "0x99cdF50A7bcD2fdBf33c26DD45e7339932EC1E85",
"transactionHash": "0xc3535bd596b7766e81e8ca40216cbe09c97ff7d301fb5fd201537560d3cabb09"
},
"1660724532588": {
"events": {},
@ -25437,7 +25437,7 @@
}
},
"schemaVersion": "3.4.9",
"updatedAt": "2022-11-03T08:04:21.670Z",
"updatedAt": "2022-11-04T05:16:53.875Z",
"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

File diff suppressed because it is too large Load Diff

View File

@ -33780,8 +33780,8 @@
}
},
"links": {},
"address": "0xAFB7b8A4d90C2Df4ce640338029d54A55BEDcfC4",
"transactionHash": "0x3177303e2c1819b33633e54ab26ff97a736bdca0a7fe8a8974ab495dab126b2d"
"address": "0xc4d42e2062C7CB4a45a0f2FECDf805b1cDDf930b",
"transactionHash": "0x287c31d3a3a2828d787be70a7d76de5e1a8d41edce4660c86266e1d85c909763"
},
"80001": {
"events": {},
@ -33869,7 +33869,7 @@
}
},
"schemaVersion": "3.4.9",
"updatedAt": "2022-11-03T08:04:04.311Z",
"updatedAt": "2022-11-04T05:16:33.839Z",
"networkType": "ethereum",
"devdoc": {
"kind": "dev",

View File

@ -3140,8 +3140,8 @@
"1338": {
"events": {},
"links": {},
"address": "0x0b19679bdEBA8Ae070534dA587cd4161D0053d75",
"transactionHash": "0xc4f4b7f2672f727be61809cbec6c69682549320c7abd09288f95b4352e25637e"
"address": "0x5Aa1721fbF48f6ee7A9122D385248f5C59E774F1",
"transactionHash": "0x076ab79e5c5f5ff6f2827a1e61f9580e76ac63ac1418cff7c40d5d300b9f3c9e"
},
"80001": {
"events": {},
@ -3235,7 +3235,7 @@
}
},
"schemaVersion": "3.4.9",
"updatedAt": "2022-11-03T08:04:21.679Z",
"updatedAt": "2022-11-04T05:16:53.883Z",
"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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -23,4 +23,7 @@ interface IBEERC1155 is IERC1155 {
returns (uint256);
function canMint(uint256 id) external view returns (bool);
function isLocked(uint256 id) external view returns (bool);
}

View File

@ -9,4 +9,6 @@ interface IBEERC721 is IERC721 {
function burn(address owner, uint256 tokenId) external;
function ownerOf(uint256 tokenId) external view returns (address owner);
function isLocked(uint256 tokenId) external view returns (bool);
}

View File

@ -0,0 +1,123 @@
// 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/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "../interfaces/IBEERC1155.sol";
import "../interfaces/IBEERC721.sol";
contract NftChipLocker is Ownable, ERC1155Holder{
mapping(address => bool) public nftTokenSupported;
using EnumerableSet for EnumerableSet.UintSet;
uint256 public constant MAX_CHIP_NUM = 4;
/**
* nft address => chip address => nftid => chip tokenid
*/
mapping( address => mapping(address => mapping(uint256 => EnumerableSet.UintSet))) chipPlugined;
/**
* nft address => chip address => chip tokenid => nftid
*/
mapping( address => mapping(address => mapping(uint256 => uint256))) chipOwner;
event ChipPlugin(
address nft,
uint256 nftId,
address chip,
uint256[] ids
);
event ChipUnplug(
address nft,
uint256 nftId,
address chip,
uint256[] ids
);
function addNFTTokenSupport(address nftToken) external onlyOwner {
nftTokenSupported[nftToken] = true;
}
function removeNFTTokenSupport(address nftToken) external onlyOwner {
nftTokenSupported[nftToken] = false;
}
function pluginChip(address nft, address chip, uint256 nftId, uint256[] memory chipIds)
external
{
require(nftTokenSupported[nft], "NftChipLocker: Unsupported NFT");
require(nftTokenSupported[chip], "NftChipLocker: Unsupported Chip");
require(!IBEERC721(nft).isLocked(nftId), "NftChipLocker: Can not pluin chip to locked token");
require(IERC721(nft).ownerOf(nftId) == msg.sender, "NftChipLocker: not owner of this nft now");
uint256 len = chipIds.length;
uint256 currentNum = pluginedChipNum(nft, chip, nftId);
require(len + currentNum <= MAX_CHIP_NUM, "NftChipLocker: reach max chip num");
uint256[] memory amounts;
for (uint256 i = 0; i < len; ++i) {
require(
IERC1155(chip).balanceOf(msg.sender, chipIds[i]) > 0,
"NftChipLocker: not enough chip"
);
require(
!IBEERC1155(chip).isLocked(chipIds[i]),
"NftChipLocker: chip is locked"
);
chipPlugined[nft][chip][nftId].add(chipIds[i]);
chipOwner[nft][chip][chipIds[i]] = nftId;
amounts[i] = 1;
}
IERC1155(chip).safeBatchTransferFrom(msg.sender, address(this), chipIds, amounts, "");
emit ChipPlugin(nft, nftId, chip, chipIds);
}
function unplugChip(address nft, address chip, uint256 nftId, uint256[] memory chipIds)
external
{
require(nftTokenSupported[nft], "NftChipLocker: Unsupported NFT");
require(nftTokenSupported[chip], "NftChipLocker: Unsupported Chip");
require(!IBEERC721(nft).isLocked(nftId), "NftChipLocker: Can not pluin chip to locked token");
require(IERC721(nft).ownerOf(nftId) == msg.sender, "NftChipLocker: not owner of this nft now");
uint256 len = chipIds.length;
uint256[] memory amounts;
for (uint256 i = 0; i < len; ++i) {
require(
chipPlugined[nft][chip][nftId].contains(chipIds[i]),
"NftChipLocker: chip not exists"
);
chipPlugined[nft][chip][nftId].remove(chipIds[i]);
delete chipOwner[nft][chip][chipIds[i]];
amounts[i] = 1;
}
IERC1155(chip).safeBatchTransferFrom(address(this), msg.sender, chipIds, amounts, "");
emit ChipUnplug(nft, nftId, chip, chipIds);
}
function chipOwnerTokenid(address nft, address chip, uint256 chipId)
external
view
returns(uint256)
{
return chipOwner[nft][chip][chipId];
}
function pluginedChipNum(address nft, address chip, uint256 tokenId)
public
view
returns(uint256)
{
return chipPlugined[nft][chip][tokenId].length();
}
function pluginedChips(address nft, address chip, uint256 tokenId)
external
view
returns(uint256[] memory)
{
return chipPlugined[nft][chip][tokenId].values();
}
}

View File

@ -5,6 +5,7 @@ import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "../../interfaces/IBEERC1155.sol";
abstract contract BEBase is ERC721, AccessControl, ERC721Enumerable, Ownable {
using Strings for uint256;
@ -15,6 +16,9 @@ abstract contract BEBase is ERC721, AccessControl, ERC721Enumerable, Ownable {
bytes32 public constant BURN_ROLE = keccak256("BURN_ROLE");
bytes32 public constant LOCK_ROLE = keccak256("LOCK_ROLE");
event Lock(uint256 indexed tokenId);
event UnLock(uint256 indexed tokenId);
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
@ -90,6 +94,7 @@ abstract contract BEBase is ERC721, AccessControl, ERC721Enumerable, Ownable {
require(_exists(tokenId), "Must be valid tokenId");
require(!lockedTokens[tokenId], "Token has already locked");
lockedTokens[tokenId] = true;
emit Lock(tokenId);
}
/**
@ -99,6 +104,7 @@ abstract contract BEBase is ERC721, AccessControl, ERC721Enumerable, Ownable {
require(_exists(tokenId), "Must be valid tokenId");
require(lockedTokens[tokenId], "Token has already unlocked");
lockedTokens[tokenId] = false;
emit UnLock(tokenId);
}
/**

View File

@ -11,6 +11,7 @@ const UserMinterFactory = artifacts.require("logic/UserMinterFactory");
const EvolveFactory = artifacts.require("logic/EvolveFactory");
const UserEvolveFactory = artifacts.require("logic/UserEvolveFactory");
const NftMall = artifacts.require("market/BENftMall");
const NftChipLocker = artifacts.require("logic/NftChipLocker");
// const BETimelockController = artifacts.require('core/BETimelockController')
module.exports = async function main(callback) {
@ -30,6 +31,8 @@ module.exports = async function main(callback) {
const coinInstance = await BECoin.deployed();
const goldInstance = await BEGold.deployed();
const nftMallInstance = await NftMall.deployed();
const lockerInstance = await NftChipLocker.deployed();
let jsons = [];
jsons.push({
name: "coin",
@ -93,6 +96,11 @@ module.exports = async function main(callback) {
json: "assets/contracts/BENftMall.json",
address: nftMallInstance.address,
});
jsons.push({
name: "nftChipLocker",
json: "assets/contracts/NftChipLocker.json",
address: lockerInstance.address,
});
console.log(JSON.stringify(jsons));
console.log(`export const userAddress = '${accounts[0]}';`);
console.log(`export const privateKey = '';`);

View File

@ -11,6 +11,7 @@ const UserMinterFactory = artifacts.require("logic/UserMinterFactory");
const EvolveFactory = artifacts.require("logic/EvolveFactory");
const UserEvolveFactory = artifacts.require("logic/UserEvolveFactory");
const NftMall = artifacts.require("market/BENftMall");
const NftChipLocker = artifacts.require("logic/NftChipLocker");
const config = require("../config/config");
@ -148,6 +149,14 @@ module.exports = async function main(callback) {
await heroInstance.setMintFactory(nftMallInstance.address);
await equipInstance.setMintFactory(nftMallInstance.address);
await chipInstance.setMintFactory(nftMallInstance.address);
console.log("update nftMallInstance settings success");
}
const lockerInstance = await NftChipLocker.deployed();
if (lockerInstance) {
await lockerInstance.addNFTTokenSupport(heroInstance.address);
await lockerInstance.addNFTTokenSupport(equipInstance.address);
await lockerInstance.addNFTTokenSupport(chipInstance.address);
console.log("update NftChipLocker addNFTTokenSupport success");
}
callback(0);
} catch (error) {

View File

@ -0,0 +1,9 @@
const NftChipLocker = artifacts.require("logic/NftChipLocker");
module.exports = async function (deployer, network, accounts) {
await deployer.deploy(NftChipLocker);
const lockerInstance = await NftChipLocker.deployed();
if (lockerInstance) {
console.log("NftChipLocker successfully deployed.");
}
};