124 lines
4.0 KiB
Solidity
124 lines
4.0 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/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();
|
|
}
|
|
|
|
}
|