add event

This commit is contained in:
owen05
2021-09-14 22:02:07 +08:00
parent 4b60736a7b
commit 6086f2ac04
8 changed files with 134 additions and 54 deletions

View File

@@ -15,6 +15,15 @@ import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol";
contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
using SafeMath for uint256;
//=================== Event ===================
event ChangeNFTInPrice(uint256 newGsStart, uint256 newCr, bool toggleFlag);
event ChangeNFTRandomOutPrice(uint256 newGsStart, uint256 newCr, bool toggleFlag);
event ChangeNFTTargetOutPrice(uint256 newGsStart, uint256 newCr, bool toggleFlag);
event ChangeNFTAmountRange(uint256 maxNFTAmount, uint256 minNFTAmount);
event ChangeTokenIdRange(uint256 nftIdStart, uint256 nftIdEnd);
event ChangeTokenIdMap(uint256 tokenIds, bool isRegistered);
event ChangeFilterName(string newFilterName);
//=================== Storage ===================
string public _FILTER_NAME_;
@@ -29,6 +38,8 @@ contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
mapping(uint256 => uint256) public _NFT_RESERVE_;
uint256[] public _NFT_IDS_;
//tokenId => index + 1 of _NFT_IDS_
mapping(uint256 => uint256) public _TOKENID_IDX_;
uint256 public _TOTAL_NFT_AMOUNT_;
uint256 public _MAX_NFT_AMOUNT_;
uint256 public _MIN_NFT_AMOUNT_;
@@ -87,12 +98,8 @@ contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
}
function getNFTIndexById(uint256 tokenId) public view returns (uint256) {
uint256 i = 0;
for (; i < _NFT_IDS_.length; i++) {
if (_NFT_IDS_[i] == tokenId) break;
}
require(i < _NFT_IDS_.length, "TOKEN_ID_NOT_EXSIT");
return i;
require(_TOKENID_IDX_[tokenId] > 0, "TOKEN_ID_NOT_EXSIT");
return _TOKENID_IDX_[tokenId] - 1;
}
//==================== Query Price ==================
@@ -197,17 +204,19 @@ contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
_GS_START_IN_ = newGsStart;
_CR_IN_ = newCr;
_NFT_IN_TOGGLE_ = true;
emit ChangeNFTInPrice(newGsStart, newCr, toggleFlag);
}
function changeNFTRandomInPrice(
function changeNFTRandomOutPrice(
uint256 newGsStart,
uint256 newCr,
bool toggleFlag
) external onlySuperOwner {
_changeNFTRandomInPrice(newGsStart, newCr, toggleFlag);
_changeNFTRandomOutPrice(newGsStart, newCr, toggleFlag);
}
function _changeNFTRandomInPrice(
function _changeNFTRandomOutPrice(
uint256 newGsStart,
uint256 newCr,
bool toggleFlag
@@ -216,6 +225,8 @@ contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
_GS_START_RANDOM_OUT_ = newGsStart;
_CR_RANDOM_OUT_ = newCr;
_NFT_RANDOM_OUT_TOGGLE_ = true;
emit ChangeNFTRandomOutPrice(newGsStart, newCr, toggleFlag);
}
function changeNFTTargetOutPrice(
@@ -235,6 +246,8 @@ contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
_GS_START_TARGET_OUT_ = newGsStart;
_CR_TARGET_OUT_ = newCr;
_NFT_TARGET_OUT_TOGGLE_ = true;
emit ChangeNFTTargetOutPrice(newGsStart, newCr, toggleFlag);
}
function changeNFTAmountRange(uint256 maxNFTAmount, uint256 minNFTAmount)
@@ -248,6 +261,8 @@ contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
require(maxNFTAmount >= minNFTAmount, "AMOUNT_INVALID");
_MAX_NFT_AMOUNT_ = maxNFTAmount;
_MIN_NFT_AMOUNT_ = minNFTAmount;
emit ChangeNFTAmountRange(maxNFTAmount, minNFTAmount);
}
function changeTokenIdRange(uint256 nftIdStart, uint256 nftIdEnd) external onlySuperOwner {
@@ -259,6 +274,8 @@ contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
_NFT_ID_START_ = nftIdStart;
_NFT_ID_END_ = nftIdEnd;
emit ChangeTokenIdRange(nftIdStart, nftIdEnd);
}
function changeTokenIdMap(uint256[] memory tokenIds, bool[] memory isRegistered)
@@ -273,6 +290,7 @@ contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
for (uint256 i = 0; i < tokenIds.length; i++) {
_SPREAD_IDS_REGISTRY_[tokenIds[i]] = isRegistered[i];
emit ChangeTokenIdMap(tokenIds[i], isRegistered[i]);
}
}
@@ -281,5 +299,6 @@ contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
onlySuperOwner
{
_FILTER_NAME_ = newFilterName;
emit ChangeFilterName(newFilterName);
}
}

View File

@@ -29,6 +29,8 @@ contract Controller is InitializableOwnable {
//==================== Event =====================
event SetEmergencyWithdraw(address filter, bool isOpen);
event SetFilterAdminFeeRateInfo(address filterAdmin, uint256 nftInFee, uint256 nftOutFee, bool isOpen);
event SetGlobalParam(uint256 nftInFee, uint256 nftOutFee);
//==================== Ownable ====================
@@ -44,11 +46,15 @@ contract Controller is InitializableOwnable {
isOpen: isOpen
});
filterAdminFeeRates[filterAdminAddr] = feeRateInfo;
emit SetFilterAdminFeeRateInfo(filterAdminAddr, nftInFeeRate, nftOutFeeRate, isOpen);
}
function setGlobalParam(uint256 nftInFeeRate, uint256 nftOutFeeRate) external onlyOwner {
_GLOBAL_NFT_IN_FEE_RATE_ = nftInFeeRate;
_GLOBAL_NFT_OUT_FEE_RATE_ = nftOutFeeRate;
emit SetGlobalParam(nftInFeeRate, nftOutFeeRate);
}
function setEmergencyWithdraw(address filter, bool isOpen) external onlyOwner {

View File

@@ -26,6 +26,8 @@ contract FilterAdmin is InitializableInternalMintableERC20 {
// ============ Event ============
event ChangeFeeRate(uint256 fee);
event AddFilter(address filter);
event FilterAdminInit(address owner, uint256 feeRate);
function init(
address owner,
@@ -47,8 +49,7 @@ contract FilterAdmin is InitializableInternalMintableERC20 {
_FILTER_REGISTRY_[filters[i]] = true;
}
//event FilterAdminInit(addres owner, uint256 feeRate)
emit FilterAdminInit(owner, feeRate);
}
function mintFragTo(address to, uint256 rawAmount) external returns (uint256) {
@@ -114,8 +115,9 @@ contract FilterAdmin is InitializableInternalMintableERC20 {
function addFilter(address[] memory filters) external onlyOwner {
for(uint256 i = 0; i < filters.length; i++) {
require(!isRegisteredFilter(filters[i]), "FILTER_ALREADY_EXIST");
_FILTERS_.push(filter[i]);
_FILTER_REGISTRY_[filter[i]] = true;
_FILTERS_.push(filters[i]);
_FILTER_REGISTRY_[filters[i]] = true;
emit AddFilter(filters[i]);
}
}

View File

@@ -17,6 +17,13 @@ import {BaseFilterV1} from "./BaseFilterV1.sol";
contract FilterERC1155V1 is IERC1155Receiver, BaseFilterV1 {
using SafeMath for uint256;
//=============== Event ==================
event FilterInit(address filterAdmin, address nftCollection, string name);
event NftIn(uint256 tokenId, uint256 amount);
event TargetOut(uint256 tokenId, uint256 amount);
event RandomOut(uint256 tokenId, uint256 amount);
event EmergencyWithdraw(address nftContract,uint256 tokenId, uint256 amount, address to);
function init(
address filterAdmin,
address nftCollection,
@@ -32,7 +39,7 @@ contract FilterERC1155V1 is IERC1155Receiver, BaseFilterV1 {
_NFT_COLLECTION_ = nftCollection;
_changeNFTInPrice(priceRules[0], priceRules[1], toggles[0]);
_changeNFTRandomInPrice(priceRules[2], priceRules[3], toggles[1]);
_changeNFTRandomOutPrice(priceRules[2], priceRules[3], toggles[1]);
_changeNFTTargetOutPrice(priceRules[4], priceRules[5], toggles[2]);
_changeNFTAmountRange(numParams[2], numParams[3]);
@@ -42,7 +49,7 @@ contract FilterERC1155V1 is IERC1155Receiver, BaseFilterV1 {
_SPREAD_IDS_REGISTRY_[spreadIds[i]] = true;
}
//event FilterInit(address filterAdmin, address nftCollection, string memory name);
emit FilterInit(filterAdmin, nftCollection, filterName);
}
// ================= Trading ================
@@ -56,21 +63,24 @@ contract FilterERC1155V1 is IERC1155Receiver, BaseFilterV1 {
for (uint256 i = 0; i < tokenIds.length; i++) {
uint256 tokenId = tokenIds[i];
require(isNFTIDValid(tokenId), "NFT_ID_NOT_SUPPORT");
totalAmount += _maintainERC1155In(tokenId);
uint256 inAmount = _maintainERC1155In(tokenId);
totalAmount += inAmount;
emit NftIn(tokenId, inAmount);
}
(uint256 rawReceive, ) = queryNFTIn(totalAmount);
received = IFilterAdmin(_OWNER_).mintFragTo(to, rawReceive);
}
function ERC1155TargetOut(
uint256[] memory indexes,
uint256[] memory tokenIds,
uint256[] memory amounts,
address to
) external preventReentrant returns (uint256 paid) {
uint256 totalAmount = 0;
for (uint256 i = 0; i < indexes.length; i++) {
for (uint256 i = 0; i < tokenIds.length; i++) {
totalAmount += amounts[i];
_transferOutERC1155(to, indexes[i], amounts[i]);
_transferOutERC1155(to, tokenIds[i], amounts[i]);
emit TargetOut(tokenIds[i], amounts[i]);
}
(uint256 rawPay, ) = queryNFTTargetOut(totalAmount);
paid = IFilterAdmin(_OWNER_).burnFragFrom(msg.sender, rawPay);
@@ -89,7 +99,8 @@ contract FilterERC1155V1 is IERC1155Receiver, BaseFilterV1 {
for (uint256 j = 0; j < _NFT_IDS_.length; j++) {
sum += _NFT_RESERVE_[_NFT_IDS_[j]];
if (sum >= randomNum) {
_transferOutERC1155(to, j, 1);
_transferOutERC1155(to, _NFT_IDS_[j], 1);
emit RandomOut( _NFT_IDS_[j], 1);
break;
}
}
@@ -120,13 +131,12 @@ contract FilterERC1155V1 is IERC1155Receiver, BaseFilterV1 {
function _transferOutERC1155(
address to,
uint256 index,
uint256 tokenId,
uint256 amount
) internal {
require(index < _NFT_IDS_.length, "INDEX_NOT_EXIST");
uint256 tokenId = _NFT_IDS_[index];
require(_TOKENID_IDX_[tokenId] > 0, "TOKENID_NOT_EXIST");
IERC1155(_NFT_COLLECTION_).safeTransferFrom(address(this), to, tokenId, amount, "");
_maintainERC1155Out(index, tokenId);
_maintainERC1155Out(tokenId);
}
function emergencyWithdraw(
@@ -149,19 +159,22 @@ contract FilterERC1155V1 is IERC1155Receiver, BaseFilterV1 {
uint256 tokenId = tokenIds[i];
IERC1155(nftContract[i]).safeTransferFrom(address(this), to, tokenId, amounts[i], "");
if (_NFT_RESERVE_[tokenId] > 0 && nftContract[i] == _NFT_COLLECTION_) {
_maintainERC1155Out(getNFTIndexById(tokenId), tokenId);
_maintainERC1155Out(tokenId);
}
emit EmergencyWithdraw(nftContract[i],tokenIds[i], amounts[i], to);
}
}
function _maintainERC1155Out(uint256 index, uint256 tokenId) internal {
function _maintainERC1155Out(uint256 tokenId) internal {
uint256 currentAmount = IERC1155(_NFT_COLLECTION_).balanceOf(address(this), tokenId);
uint256 outAmount = _NFT_RESERVE_[tokenId].sub(currentAmount);
_NFT_RESERVE_[tokenId] = currentAmount;
_TOTAL_NFT_AMOUNT_ -= outAmount;
if (currentAmount == 0) {
uint256 index = _TOKENID_IDX_[tokenId] - 1;
_NFT_IDS_[index] = _NFT_IDS_[_NFT_IDS_.length - 1];
_NFT_IDS_.pop();
_TOKENID_IDX_[tokenId] = 0;
}
}
@@ -171,6 +184,7 @@ contract FilterERC1155V1 is IERC1155Receiver, BaseFilterV1 {
if (_NFT_RESERVE_[tokenId] == 0 && currentAmount > 0) {
_NFT_IDS_.push(tokenId);
}
_TOKENID_IDX_[tokenId] = _NFT_IDS_.length;
_NFT_RESERVE_[tokenId] = currentAmount;
_TOTAL_NFT_AMOUNT_ += inAmount;
}

View File

@@ -20,6 +20,13 @@ import {BaseFilterV1} from "./BaseFilterV1.sol";
contract FilterERC721V1 is IERC721Receiver, BaseFilterV1 {
using SafeMath for uint256;
//============== Event =================
event FilterInit(address filterAdmin, address nftCollection, string name);
event NftIn(uint256 tokenId);
event TargetOut(uint256 tokenId);
event RandomOut(uint256 tokenId);
event EmergencyWithdraw(address nftContract,uint256 tokenId, address to);
function init(
address filterAdmin,
address nftCollection,
@@ -34,7 +41,7 @@ contract FilterERC721V1 is IERC721Receiver, BaseFilterV1 {
_NFT_COLLECTION_ = nftCollection;
_changeNFTInPrice(priceRules[0], priceRules[1], toggles[0]);
_changeNFTRandomInPrice(priceRules[2], priceRules[3], toggles[1]);
_changeNFTRandomOutPrice(priceRules[2], priceRules[3], toggles[1]);
_changeNFTTargetOutPrice(priceRules[4], priceRules[5], toggles[2]);
_changeNFTAmountRange(numParams[2], numParams[3]);
@@ -44,7 +51,7 @@ contract FilterERC721V1 is IERC721Receiver, BaseFilterV1 {
_SPREAD_IDS_REGISTRY_[spreadIds[i]] = true;
}
//event FilterInit(address filterAdmin, address nftCollection, string memory name);
emit FilterInit(filterAdmin, nftCollection, filterName);
}
// ================= Trading ================
@@ -63,24 +70,27 @@ contract FilterERC721V1 is IERC721Receiver, BaseFilterV1 {
"NFT_NOT_SEND"
);
_NFT_IDS_.push(tokenId);
_TOKENID_IDX_[tokenId] = _NFT_IDS_.length;
_NFT_RESERVE_[tokenId] = 1;
//event Erc721TokenIn(uint256 index, uint256 tokenId);
emit NftIn(tokenId);
}
_TOTAL_NFT_AMOUNT_ = _NFT_IDS_.length;
(uint256 rawReceive, ) = queryNFTIn(tokenIds.length);
received = IFilterAdmin(_OWNER_).mintFragTo(to, rawReceive);
}
function ERC721TargetOut(uint256[] memory indexes, address to)
function ERC721TargetOut(uint256[] memory tokenIds, address to)
external
preventReentrant
returns (uint256 paid)
{
(uint256 rawPay, ) = queryNFTTargetOut(indexes.length);
(uint256 rawPay, ) = queryNFTTargetOut(tokenIds.length);
paid = IFilterAdmin(_OWNER_).burnFragFrom(msg.sender, rawPay);
for (uint256 i = 0; i < indexes.length; i++) {
_transferOutERC721(to, indexes[i]);
for (uint256 i = 0; i < tokenIds.length; i++) {
_transferOutERC721(to, tokenIds[i]);
emit TargetOut(tokenIds[i]);
}
_TOTAL_NFT_AMOUNT_ = _NFT_IDS_.length;
}
@@ -93,7 +103,10 @@ contract FilterERC721V1 is IERC721Receiver, BaseFilterV1 {
(uint256 rawPay, ) = queryNFTRandomOut(amount);
paid = IFilterAdmin(_OWNER_).burnFragFrom(msg.sender, rawPay);
for (uint256 i = 0; i < amount; i++) {
_transferOutERC721(to, _getRandomNum() % _TOTAL_NFT_AMOUNT_);
uint256 index = _getRandomNum() % _TOTAL_NFT_AMOUNT_;
_transferOutERC721(to, _NFT_IDS_[index]);
emit RandomOut(_NFT_IDS_[index]);
}
_TOTAL_NFT_AMOUNT_ = _NFT_IDS_.length;
}
@@ -109,16 +122,15 @@ contract FilterERC721V1 is IERC721Receiver, BaseFilterV1 {
return IERC721Receiver.onERC721Received.selector;
}
function _transferOutERC721(address to, uint256 index) internal {
require(index < _NFT_IDS_.length, "INDEX_NOT_EXIST");
uint256 tokenId = _NFT_IDS_[index];
function _transferOutERC721(address to, uint256 tokenId) internal {
require(_TOKENID_IDX_[tokenId] > 0, "TOKENID_NOT_EXIST");
uint256 index = _TOKENID_IDX_[tokenId] - 1;
require(index < _NFT_IDS_.length, "INDEX_INVALID");
IERC721(_NFT_COLLECTION_).safeTransferFrom(address(this), to, tokenId);
_NFT_IDS_[index] = _NFT_IDS_[_NFT_IDS_.length - 1];
_NFT_IDS_.pop();
_NFT_RESERVE_[tokenId] = 0;
//idx,oldTokenId,newTokenId
//event Erc721Out(uint256 index, uint256 tokenId)
_TOKENID_IDX_[tokenId] = 0;
}
function emergencyWithdraw(
@@ -142,6 +154,7 @@ contract FilterERC721V1 is IERC721Receiver, BaseFilterV1 {
_NFT_RESERVE_[tokenId] = 0;
}
IERC721(nftContract[i]).safeTransferFrom(address(this), to, tokenIds[i]);
emit EmergencyWithdraw(nftContract[i],tokenIds[i],to);
}
_TOTAL_NFT_AMOUNT_ = _NFT_IDS_.length;
}

View File

@@ -39,14 +39,14 @@ interface IFilter {
function ERC721In(uint256[] memory tokenIds, address to) external returns (uint256 received);
function ERC721TargetOut(uint256[] memory indexes, address to) external returns (uint256 paid);
function ERC721TargetOut(uint256[] memory tokenIds, address to) external returns (uint256 paid);
function ERC721RandomOut(uint256 amount, address to) external returns (uint256 paid);
function ERC1155In(uint256[] memory tokenIds, address to) external returns (uint256 received);
function ERC1155TargetOut(
uint256[] memory indexes,
uint256[] memory tokenIds,
uint256[] memory amounts,
address to
) external returns (uint256 paid);

View File

@@ -27,6 +27,7 @@ contract DODONFTApprove is InitializableOwnable {
// ============ Events ============
event AddDODOProxy(address dodoProxy);
event RemoveDODOProxy(address oldProxy);
// ============ Modifiers ============
modifier notLocked() {
@@ -62,6 +63,7 @@ contract DODONFTApprove is InitializableOwnable {
function removeDODOProxy (address oldDodoProxy) external onlyOwner {
_IS_ALLOWED_PROXY_[oldDodoProxy] = false;
emit RemoveDODOProxy(oldDodoProxy);
}

View File

@@ -33,6 +33,20 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
// ============ Event ==============
event SetFilterTemplate(uint256 idx, address filterTemplate);
event Erc721In(address filter, address to, uint256 received);
event Erc1155In(address filter, address to, uint256 received);
event Erc721TargetOut(address filter, address to, uint256 paid);
event Erc1155TargetOut(address filter, address to, uint256 paid);
event Erc721RandomOut(address filter, address to, uint256 paid);
event Erc1155RandomOut(address filter, address to, uint256 paid);
event CreateNFTPool(address newFilterAdmin, address filter);
event CreateFilterV1(address newFilterV1, uint256 filterTemplateKey);
event Erc721toErc20(address nftContract, uint256 tokenId, address toToken, uint256 returnAmount);
event ChangeMaintainer(address newMaintainer);
event ChangeContoller(address newController);
event ChangeFilterAdminTemplate(address newFilterAdminTemplate);
constructor(
address cloneFactory,
@@ -65,19 +79,19 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
uint256 received = IFilter(filter).ERC721In(tokenIds, to);
require(received >= minMintAmount, "MINT_AMOUNT_NOT_ENOUGH");
//event Erc721In(address filter, address to, uint256 received);
emit Erc721In(filter, to, received);
}
function erc721TargetOut(
address filter,
uint256[] memory indexes,//tokenId
uint256[] memory tokenIds,
address to,
uint256 maxBurnAmount
) external {
uint256 paid = IFilter(filter).ERC721TargetOut(indexes, to);
uint256 paid = IFilter(filter).ERC721TargetOut(tokenIds, to);
require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED");
//event Erc721TargetOut(address filter, address to, uint256 paid);
emit Erc721TargetOut(filter, to, paid);
}
function erc721RandomOut(
@@ -89,7 +103,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
uint256 paid = IFilter(filter).ERC721RandomOut(amount, to);
require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED");
//event Erc721TargetOut(address filter, address to, uint256 paid);
emit Erc721RandomOut(filter, to, paid);
}
// ================== ERC1155 In and Out ===================
@@ -107,17 +121,21 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
IDODONFTApprove(_DODO_NFT_APPROVE_).claimERC1155Batch(nftCollection, msg.sender, filter, tokenIds, amounts);
uint256 received = IFilter(filter).ERC1155In(tokenIds, to);
require(received >= minMintAmount, "MINT_AMOUNT_NOT_ENOUGH");
emit Erc1155In(filter, to, received);
}
function erc1155TargetOut(
address filter,
uint256[] memory indexes,
uint256[] memory tokenIds,
uint256[] memory amounts,
address to,
uint256 maxBurnAmount
) external {
uint256 paid = IFilter(filter).ERC1155TargetOut(indexes, amounts, to);
uint256 paid = IFilter(filter).ERC1155TargetOut(tokenIds, amounts, to);
require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED");
emit Erc1155TargetOut(filter, to, paid);
}
function erc1155RandomOut(
@@ -128,6 +146,8 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
) external {
uint256 paid = IFilter(filter).ERC1155RandomOut(amount, to);
require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED");
emit Erc1155RandomOut(filter, to, paid);
}
@@ -169,7 +189,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
filters
);
//event CreateNFTPool(address newFilterAdmin, address filterV1);
emit CreateNFTPool(newFilterAdmin, filterV1);
}
// ================== Create Filter ===================
@@ -194,7 +214,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
spreadIds
);
//event CreateFilterV1(address newFilterV1, uint256 filterTemplateKey);
emit CreateFilterV1(newFilterV1, key);
}
@@ -226,21 +246,25 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
uint256 returnAmount = _generalBalanceOf(toToken, address(this));
_generalTransfer(toToken, msg.sender, returnAmount);
emit Erc721toErc20(nftContract, tokenId, toToken, returnAmount);
}
//====================== Ownable ========================
function changeMaintainer(address newMaintainer) external onlyOwner {
_MAINTAINER_ = newMaintainer;
emit ChangeMaintainer(newMaintainer);
}
function changeFilterAdminTemplate(address newFilterAdminTemplate) external onlyOwner {
_FILTER_ADMIN_TEMPLATE_ = newFilterAdminTemplate;
emit ChangeFilterAdminTemplate(newFilterAdminTemplate);
}
function changeController(address newControllerModel) external onlyOwner {
_CONTROLLER_ = newControllerModel;
//event ChangeContoller(address newController);
function changeController(address newController) external onlyOwner {
_CONTROLLER_ = newController;
emit ChangeContoller(newController);
}
function setFilterTemplate(uint256 idx, address newFilterTemplate) external onlyOwner {