文件 1 的 19:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 19:ERC1155Holder.sol
pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol";
contract ERC1155Holder is ERC1155Receiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}
文件 3 的 19:ERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
}
}
文件 4 的 19:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 5 的 19:ERC721Holder.sol
pragma solidity ^0.8.0;
import "../IERC721Receiver.sol";
contract ERC721Holder is IERC721Receiver {
function onERC721Received(
address,
address,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}
文件 6 的 19:FractonSwap.sol
pragma solidity ^0.8.9;
import '@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol';
import '@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/token/ERC721/IERC721.sol';
import '@openzeppelin/contracts/token/ERC1155/IERC1155.sol';
import '@openzeppelin/contracts/access/Ownable.sol';
import '@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol';
import '@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol';
import '../interface/IFractonMiniNFT.sol';
import '../interface/IFractonFFT.sol';
import '../interface/IFractonSwap.sol';
import '../interface/IFractonTokenFactory.sol';
contract FractonSwap is
ERC721Holder,
ERC1155Holder,
Ownable,
IFractonSwap,
VRFConsumerBaseV2
{
uint256 public swapRate = 1E21;
uint256 public fftTax = 3E18;
uint256 public nftTax = 3;
address public tokenFactory;
address public vrfRescuer;
mapping(uint256 => ChainLinkRequest) public chainLinkRequests;
mapping(address => uint256[]) public NFTIds;
mapping(address => address) public NFTtoMiniNFT;
mapping(address => address) public miniNFTtoFFT;
VRFCoordinatorV2Interface COORDINATOR;
bytes32 public keyHash;
uint32 public callbackGasLimit = 1000000;
uint32 public numWords = 1;
uint16 public requestConfirmations = 3;
uint64 public subscriptionId;
uint256[] public s_randomWords;
constructor(
address vrfCoordinator_,
address vrfRescuer_,
bytes32 keyHash_,
uint64 subscriptionId_
) VRFConsumerBaseV2(vrfCoordinator_) {
COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator_);
vrfRescuer = vrfRescuer_;
keyHash = keyHash_;
subscriptionId = subscriptionId_;
}
modifier onlyDAO() {
address dao = IFractonTokenFactory(tokenFactory).getDAOAddress();
require(msg.sender == dao, 'Fracton: caller is not Fracton DAO');
_;
}
modifier onlyFactoryOrOwner() {
require(
msg.sender == tokenFactory || msg.sender == owner(),
'Invalid Caller'
);
_;
}
function updatePoolRelation(
address miniNFT,
address FFT,
address NFT
) external virtual override onlyFactoryOrOwner returns (bool) {
miniNFTtoFFT[miniNFT] = FFT;
NFTtoMiniNFT[NFT] = miniNFT;
emit UpdatePoolRelation(msg.sender, miniNFT, FFT, NFT);
return true;
}
function poolClaim(address miniNFTContract, uint256 tokenID)
external
virtual
override
returns (bool)
{
require(
miniNFTtoFFT[miniNFTContract] != address(0),
'swap: invalid contract'
);
require(IFractonMiniNFT(miniNFTContract).claimBlindBox(tokenID) > 0);
emit PoolClaim(msg.sender, miniNFTContract, tokenID);
return true;
}
function swapMiniNFTtoFFT(
address miniNFTContract,
uint256 tokenID,
uint256 amount
) external virtual override returns (bool) {
require(
miniNFTtoFFT[miniNFTContract] != address(0),
'swap: invalid contract'
);
uint256 miniNFTBalance = IERC1155(miniNFTContract).balanceOf(
msg.sender,
tokenID
);
require(miniNFTBalance >= amount, 'swap: balance insufficient');
IERC1155(miniNFTContract).safeTransferFrom(
msg.sender,
address(this),
tokenID,
amount,
''
);
require(
IFractonFFT(miniNFTtoFFT[miniNFTContract]).swapmint(
amount * swapRate,
msg.sender
)
);
emit SwapMiniNFTtoFFT(msg.sender, miniNFTContract, tokenID, amount);
return true;
}
function swapFFTtoMiniNFT(address miniNFTContract, uint256 miniNFTAmount)
external
virtual
override
returns (bool)
{
require(
miniNFTtoFFT[miniNFTContract] != address(0),
'swap: invalid contract'
);
require(
IERC1155(miniNFTContract).balanceOf(address(this), 0) >= miniNFTAmount,
'swap:insufficient miniNFT in pool'
);
uint256 FFTamount = miniNFTAmount * swapRate;
uint256 taxfee = miniNFTAmount * fftTax;
require(
IFractonFFT(miniNFTtoFFT[miniNFTContract]).burnFrom(msg.sender, FFTamount)
);
require(
IFractonFFT(miniNFTtoFFT[miniNFTContract]).transferFrom(
msg.sender,
IFractonTokenFactory(tokenFactory).getVaultAddress(),
taxfee
)
);
IERC1155(miniNFTContract).safeTransferFrom(
address(this),
msg.sender,
0,
miniNFTAmount,
''
);
emit SwapFFTtoMiniNFT(msg.sender, miniNFTContract, miniNFTAmount);
return true;
}
function swapMiniNFTtoNFT(address NFTContract)
external
virtual
override
returns (bool)
{
address miniNFTContract = NFTtoMiniNFT[NFTContract];
require(miniNFTContract != address(0), 'swap: invalid contract');
require(NFTIds[NFTContract].length > 0, 'swap: no NFT left');
uint256 requestId = COORDINATOR.requestRandomWords(
keyHash,
subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
chainLinkRequests[requestId] = ChainLinkRequest(msg.sender, NFTContract);
emit SendChainlinkVRF(requestId, msg.sender, NFTContract);
return true;
}
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords)
internal
virtual
override
{
address sender = chainLinkRequests[requestId].sender;
address NFTContract = chainLinkRequests[requestId].nft;
address miniNFTContract = NFTtoMiniNFT[NFTContract];
uint256 NFTNumber = NFTIds[NFTContract].length;
require(NFTNumber > 0, 'swap: no NFT left');
uint256 NFTIndex = randomWords[0] % NFTNumber;
uint256 NFTID = NFTIds[NFTContract][NFTIndex];
NFTIds[NFTContract][NFTIndex] = NFTIds[NFTContract][NFTNumber - 1];
NFTIds[NFTContract].pop();
IERC1155(miniNFTContract).safeTransferFrom(
sender,
address(this),
0,
1000,
''
);
IFractonMiniNFT(miniNFTContract).burn(1000);
IERC1155(miniNFTContract).safeTransferFrom(
sender,
IFractonTokenFactory(tokenFactory).getVaultAddress(),
0,
nftTax,
''
);
IERC721(NFTContract).transferFrom(address(this), sender, NFTID);
emit SwapMiniNFTtoNFT(sender, NFTContract, NFTID);
}
function swapNFTtoMiniNFT(
address NFTContract,
address fromOwner,
uint256 tokenId
) external virtual override onlyDAO returns (bool) {
address miniNFTContract = NFTtoMiniNFT[NFTContract];
require(miniNFTContract != address(0), 'swap: invalid contract');
IERC721(NFTContract).safeTransferFrom(fromOwner, address(this), tokenId);
require(IFractonMiniNFT(miniNFTContract).swapmint(1000, fromOwner));
return true;
}
function withdrawERC20(address project, uint256 amount)
external
onlyDAO
returns (bool)
{
require(
IERC20(project).transfer(msg.sender, amount),
'swap: withdraw failed'
);
return true;
}
function withdrawERC721(address airdropContract, uint256 tokenId)
external
onlyDAO
returns (bool)
{
require(
NFTtoMiniNFT[airdropContract] == address(0),
'swap: cannot withdraw ProjectNFT'
);
IERC721(airdropContract).safeTransferFrom(
address(this),
msg.sender,
tokenId
);
return true;
}
function withdrawERC1155(
address airdropContract,
uint256 tokenId,
uint256 amount
) external onlyDAO returns (bool) {
require(
miniNFTtoFFT[airdropContract] == address(0),
'swap: cannot withdraw ProjectNFT'
);
IERC1155(airdropContract).safeTransferFrom(
address(this),
msg.sender,
tokenId,
amount,
''
);
return true;
}
function updateFactory(address factory_) external onlyOwner returns (bool) {
require(tokenFactory == address(0), 'swap: factory has been set');
require(factory_ != address(0), 'swap: factory can not be 0 address');
tokenFactory = factory_;
emit UpdateFactory(factory_);
return true;
}
function updateTax(uint256 fftTax_, uint256 nftTax_)
external
onlyDAO
returns (bool)
{
fftTax = fftTax_;
nftTax = nftTax_;
emit UpdateTax(fftTax_, nftTax_);
return true;
}
function updateCallbackGasLimit(uint32 gasLimit_)
external
override
onlyDAO
returns (bool)
{
callbackGasLimit = gasLimit_;
return true;
}
function emergencyUpdateVrf(address vrfCoordinator_) external {
require(msg.sender == vrfRescuer, 'swap: invalid caller');
require(vrfCoordinator_ != address(0), 'swap: invaild coordiantor address');
COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator_);
}
function updateVrfSubscriptionId(uint64 subscriptionId_)
external
override
onlyDAO
returns (bool)
{
subscriptionId = subscriptionId_;
return true;
}
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) public virtual override returns (bytes4) {
NFTIds[msg.sender].push(tokenId);
return super.onERC721Received(operator, from, tokenId, data);
}
function numberOfNFT(address NFTContract) external view returns (uint256) {
return NFTIds[NFTContract].length;
}
}
文件 7 的 19:IERC1155.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155 is IERC165 {
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 8 的 19:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 9 的 19:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 10 的 19:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
文件 11 的 19:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool _approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 12 的 19:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 13 的 19:IFractonFFT.sol
pragma solidity ^0.8.9;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
interface IFractonFFT is IERC20 {
event SetPercent(uint256 vaultPercent, uint256 pfVaultPercent);
function swapmint(uint256 amount, address to) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function multiTransfer(address[] memory receivers, uint256[] memory amounts)
external;
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
function burnFrom(address from, uint256 value) external returns (bool);
function isExcludedFromFee(address account) external view returns (bool);
function updateFee(uint256 vaultPercent_, uint256 pfVaultPercent_)
external
returns (bool);
}
文件 14 的 19:IFractonMiniNFT.sol
pragma solidity ^0.8.9;
interface IFractonMiniNFT {
event StartNewRound(uint256 blockNumber, uint256 sellingPrice);
event CloseRound(uint256 blockNumber);
event ClaimBlindBox(address owner, uint256 tokenID, uint256 amount);
event WithdrawEther(address caller, uint256 amount);
event UpdateRoundSucceed(uint256 round, uint256 blockNumber);
event UpdateBlindBoxPrice(uint256 price);
function startNewRound(uint256 sellingPrice) external returns (bool);
function closeRound() external returns (bool);
function mintBlindBox(uint256 amount) external payable returns (uint256);
function claimBlindBox(uint256 tokenID) external returns (uint256);
function withdrawEther() external returns (bool);
function updateRoundSucceed(uint256 round) external returns (bool);
function updateBlindBoxPrice(uint256 BBoxPrice) external returns (bool);
function totalSupply(uint256 id) external view returns (uint256);
function burn(uint256 amount) external;
function swapmint(uint256 amount, address to) external returns (bool);
}
文件 15 的 19:IFractonSwap.sol
pragma solidity ^0.8.9;
interface IFractonSwap {
event UpdatePoolRelation(
address editor,
address miniNFT,
address FFT,
address NFT
);
event PoolClaim(address owner, address miniNFTcontract, uint256 tokenID);
event SwapMiniNFTtoFFT(
address owner,
address miniNFTcontract,
uint256 tokenID,
uint256 miniNFTAmount
);
event SwapFFTtoMiniNFT(
address owner,
address miniNFTcontract,
uint256 miniNFTAmount
);
event SendChainlinkVRF(
uint256 requestId,
address sender,
address NFTContract
);
event SwapMiniNFTtoNFT(address owner, address NFTContract, uint256 NFTID);
event UpdateFactory(address factory);
event UpdateTax(uint256 fftTax, uint256 nftTax);
struct ChainLinkRequest {
address sender;
address nft;
}
function updatePoolRelation(
address miniNFT,
address FFT,
address NFT
) external returns (bool);
function poolClaim(address miniNFTcontract, uint256 tokenID)
external
returns (bool);
function swapMiniNFTtoFFT(
address miniNFTcontract,
uint256 tokenID,
uint256 amount
) external returns (bool);
function swapFFTtoMiniNFT(address miniNFTcontract, uint256 miniNFTamount)
external
returns (bool);
function swapMiniNFTtoNFT(address NFTContract) external returns (bool);
function swapNFTtoMiniNFT(
address NFTContract,
address fromOwner,
uint256 tokenId
) external returns (bool);
function updateCallbackGasLimit(uint32 gasLimit_) external returns (bool);
function updateVrfSubscriptionId(uint64 subscriptionId_)
external
returns (bool);
}
文件 16 的 19:IFractonTokenFactory.sol
pragma solidity ^0.8.9;
interface IFractonTokenFactory {
function getowner() external view returns (address);
function getDAOAddress() external view returns (address);
function getVaultAddress() external view returns (address);
function getSwapAddress() external view returns (address);
function getPoolFundingVaultAddress() external view returns (address);
}
文件 17 的 19:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 18 的 19:VRFConsumerBaseV2.sol
pragma solidity ^0.8.4;
abstract contract VRFConsumerBaseV2 {
error OnlyCoordinatorCanFulfill(address have, address want);
address private immutable vrfCoordinator;
constructor(address _vrfCoordinator) {
vrfCoordinator = _vrfCoordinator;
}
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual;
function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external {
if (msg.sender != vrfCoordinator) {
revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator);
}
fulfillRandomWords(requestId, randomWords);
}
}
文件 19 的 19:VRFCoordinatorV2Interface.sol
pragma solidity ^0.8.0;
interface VRFCoordinatorV2Interface {
function getRequestConfig()
external
view
returns (
uint16,
uint32,
bytes32[] memory
);
function requestRandomWords(
bytes32 keyHash,
uint64 subId,
uint16 minimumRequestConfirmations,
uint32 callbackGasLimit,
uint32 numWords
) external returns (uint256 requestId);
function createSubscription() external returns (uint64 subId);
function getSubscription(uint64 subId)
external
view
returns (
uint96 balance,
uint64 reqCount,
address owner,
address[] memory consumers
);
function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external;
function acceptSubscriptionOwnerTransfer(uint64 subId) external;
function addConsumer(uint64 subId, address consumer) external;
function removeConsumer(uint64 subId, address consumer) external;
function cancelSubscription(uint64 subId, address to) external;
}
{
"compilationTarget": {
"contracts/fundraising/FractonSwap.sol": "FractonSwap"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"vrfCoordinator_","type":"address"},{"internalType":"address","name":"vrfRescuer_","type":"address"},{"internalType":"bytes32","name":"keyHash_","type":"bytes32"},{"internalType":"uint64","name":"subscriptionId_","type":"uint64"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"have","type":"address"},{"internalType":"address","name":"want","type":"address"}],"name":"OnlyCoordinatorCanFulfill","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"miniNFTcontract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"PoolClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"NFTContract","type":"address"}],"name":"SendChainlinkVRF","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"miniNFTcontract","type":"address"},{"indexed":false,"internalType":"uint256","name":"miniNFTAmount","type":"uint256"}],"name":"SwapFFTtoMiniNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"miniNFTcontract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"miniNFTAmount","type":"uint256"}],"name":"SwapMiniNFTtoFFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"NFTContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"NFTID","type":"uint256"}],"name":"SwapMiniNFTtoNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"factory","type":"address"}],"name":"UpdateFactory","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"editor","type":"address"},{"indexed":false,"internalType":"address","name":"miniNFT","type":"address"},{"indexed":false,"internalType":"address","name":"FFT","type":"address"},{"indexed":false,"internalType":"address","name":"NFT","type":"address"}],"name":"UpdatePoolRelation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fftTax","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nftTax","type":"uint256"}],"name":"UpdateTax","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"NFTIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"NFTtoMiniNFT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callbackGasLimit","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"chainLinkRequests","outputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"nft","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vrfCoordinator_","type":"address"}],"name":"emergencyUpdateVrf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fftTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keyHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"miniNFTtoFFT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numWords","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"NFTContract","type":"address"}],"name":"numberOfNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"miniNFTContract","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"poolClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"name":"rawFulfillRandomWords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestConfirmations","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"s_randomWords","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"subscriptionId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"miniNFTContract","type":"address"},{"internalType":"uint256","name":"miniNFTAmount","type":"uint256"}],"name":"swapFFTtoMiniNFT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"miniNFTContract","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"swapMiniNFTtoFFT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"NFTContract","type":"address"}],"name":"swapMiniNFTtoNFT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"NFTContract","type":"address"},{"internalType":"address","name":"fromOwner","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"swapNFTtoMiniNFT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"gasLimit_","type":"uint32"}],"name":"updateCallbackGasLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"factory_","type":"address"}],"name":"updateFactory","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"miniNFT","type":"address"},{"internalType":"address","name":"FFT","type":"address"},{"internalType":"address","name":"NFT","type":"address"}],"name":"updatePoolRelation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fftTax_","type":"uint256"},{"internalType":"uint256","name":"nftTax_","type":"uint256"}],"name":"updateTax","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"subscriptionId_","type":"uint64"}],"name":"updateVrfSubscriptionId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vrfRescuer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"airdropContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawERC1155","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"project","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawERC20","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"airdropContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"withdrawERC721","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]