This commit is contained in:
owen05
2021-09-10 21:16:47 +08:00
parent 09a4cbfc9c
commit 4deca2be13
7 changed files with 55 additions and 60 deletions

View File

@@ -8,9 +8,7 @@
- contracts/NFTPool/impl/FilterERC1155V1.sol - contracts/NFTPool/impl/FilterERC1155V1.sol
- contracts/NFTPool/impl/ControllerModel.sol - contracts/NFTPool/impl/Controller.sol
- contracts/external/ERC20/InitializableInternalMintableERC20.sol
- contracts/SmartRoute/proxies/DODONFTPoolProxy.sol - contracts/SmartRoute/proxies/DODONFTPoolProxy.sol

View File

@@ -99,57 +99,54 @@ contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
public public
view view
returns ( returns (
uint256 received, uint256 rawReceive,
uint256 poolFee, uint256 received
uint256 mtFee
) )
{ {
require(NFTInAmount <= getAvaliableNFTIn(), "EXCEDD_IN_AMOUNT"); require(NFTInAmount <= getAvaliableNFTInAmount(), "EXCEDD_IN_AMOUNT");
rawReceive = _geometricCalc( rawReceive = _geometricCalc(
_GS_START_IN_, _GS_START_IN_,
_CR_IN_, _CR_IN_,
_TOTAL_NFT_AMOUNT_, _TOTAL_NFT_AMOUNT_,
_TOTAL_NFT_AMOUNT_ + NFTInAmount _TOTAL_NFT_AMOUNT_ + NFTInAmount
); );
(poolFee, mtFee, received) = IFilterAdmin(_OWNER_).queryChargeMintFee(rawReceive); (,, received) = IFilterAdmin(_OWNER_).queryMintFee(rawReceive);
} }
function queryNFTTargetOut(uint256 NFTOutAmount) function queryNFTTargetOut(uint256 NFTOutAmount)
public public
view view
returns ( returns (
uint256 paid, uint256 rawPay,
uint256 poolFee, uint256 pay
uint256 mtFee
) )
{ {
require(NFTOutAmount <= getAvaliableNFTOut(), "EXCEED_OUT_AMOUNT"); require(NFTOutAmount <= getAvaliableNFTOutAmount(), "EXCEED_OUT_AMOUNT");
rawPay = _geometricCalc( rawPay = _geometricCalc(
_GS_START_TARGET_OUT_, _GS_START_TARGET_OUT_,
_CR_TARGET_OUT_, _CR_TARGET_OUT_,
_TOTAL_NFT_AMOUNT_ - NFTOutAmount, _TOTAL_NFT_AMOUNT_ - NFTOutAmount,
_TOTAL_NFT_AMOUNT_ _TOTAL_NFT_AMOUNT_
); );
(poolFee, mtFee, paid) = IFilterAdmin(_OWNER_).queryChargeBurnFee(rawPay); (,, pay) = IFilterAdmin(_OWNER_).queryBurnFee(rawPay);
} }
function queryNFTRandomOut(uint256 NFTOutAmount) function queryNFTRandomOut(uint256 NFTOutAmount)
public public
view view
returns ( returns (
uint256 paid, uint256 rawPay,
uint256 poolFee, uint256 pay
uint256 mtFee
) )
{ {
require(NFTOutAmount <= getAvaliableNFTOut(), "EXCEED_OUT_AMOUNT"); require(NFTOutAmount <= getAvaliableNFTOutAmount(), "EXCEED_OUT_AMOUNT");
rawPay = _geometricCalc( rawPay = _geometricCalc(
_GS_START_RANDOM_OUT_, _GS_START_RANDOM_OUT_,
_CR_RANDOM_OUT_, _CR_RANDOM_OUT_,
_TOTAL_NFT_AMOUNT_ - NFTOutAmount, _TOTAL_NFT_AMOUNT_ - NFTOutAmount,
_TOTAL_NFT_AMOUNT_ _TOTAL_NFT_AMOUNT_
); );
(poolFee, mtFee, paid) = IFilterAdmin(_OWNER_).queryChargeBurnFee(rawPay); (,, pay) = IFilterAdmin(_OWNER_).queryBurnFee(rawPay);
} }
// ============ Math ============= // ============ Math =============
@@ -161,7 +158,7 @@ contract BaseFilterV1 is InitializableOwnable, ReentrancyGuard {
uint256 end uint256 end
) internal view returns (uint256) { ) internal view returns (uint256) {
if (q == DecimalMath.ONE) { if (q == DecimalMath.ONE) {
return end.sub(start).ml(a1); return end.sub(start).mul(a1);
} }
//Sn=a1*(q^n-1)/(q-1) //Sn=a1*(q^n-1)/(q-1)
//Sn-Sm = a1*(q^n-q^m)/(q-1) //Sn-Sm = a1*(q^n-q^m)/(q-1)

View File

@@ -60,20 +60,20 @@ contract Controller is InitializableOwnable {
function getMintFeeRate(address filterAdminAddr) external view returns (uint256) { function getMintFeeRate(address filterAdminAddr) external view returns (uint256) {
FilterAdminFeeRateInfo memory filterAdminFeeRateInfo = filterAdminFeeRates[filterAdminAddr]; FilterAdminFeeRateInfo memory filterAdminFeeRateInfo = filterAdminFeeRates[filterAdminAddr];
if (filterAdminFeeRateInfo.isSet) { if (filterAdminFeeRateInfo.isOpen) {
return filterAdminFeeRateInfo.nftInFeeRate; return filterAdminFeeRateInfo.nftInFeeRate;
} else { } else {
return _GLOBAL_NFT_IN_FEERate_; return _GLOBAL_NFT_IN_FEE_RATE_;
} }
} }
function getBurnFeeRate(address filterAdminAddr) external view returns (uint256) { function getBurnFeeRate(address filterAdminAddr) external view returns (uint256) {
FilterAdminFeeInfo memory filterAdminFeeInfo = filterAdminFees[filterAdminAddr]; FilterAdminFeeRateInfo memory filterAdminFeeInfo = filterAdminFeeRates[filterAdminAddr];
if (filterAdminFeeInfo.isSet) { if (filterAdminFeeInfo.isOpen) {
return filterAdminFeeInfo.nftOutFee; return filterAdminFeeInfo.nftOutFeeRate;
} else { } else {
return _GLOBAL_NFT_OUT_FEE_; return _GLOBAL_NFT_OUT_FEE_RATE_;
} }
} }
} }

View File

@@ -56,7 +56,7 @@ contract FilterAdmin is InitializableInternalMintableERC20 {
if (mtFee > 0) _mint(_MAINTAINER_, mtFee); if (mtFee > 0) _mint(_MAINTAINER_, mtFee);
_mint(to, received); _mint(to, received);
return received return received;
} }
function burnFragFrom(address from, uint256 rawAmount) external returns (uint256) { function burnFragFrom(address from, uint256 rawAmount) external returns (uint256) {
@@ -79,7 +79,7 @@ contract FilterAdmin is InitializableInternalMintableERC20 {
uint256 afterChargedAmount uint256 afterChargedAmount
) )
{ {
uint256 mtFeeRate = IController(_CONTROLLER_).getMintFee(address(this)); uint256 mtFeeRate = IController(_CONTROLLER_).getMintFeeRate(address(this));
poolFee = DecimalMath.mulFloor(rawAmount, _FEE_RATE_); poolFee = DecimalMath.mulFloor(rawAmount, _FEE_RATE_);
mtFee = DecimalMath.mulFloor(rawAmount, mtFeeRate); mtFee = DecimalMath.mulFloor(rawAmount, mtFeeRate);
afterChargedAmount = rawAmount.sub(poolFee).sub(mtFee); afterChargedAmount = rawAmount.sub(poolFee).sub(mtFee);
@@ -93,14 +93,14 @@ contract FilterAdmin is InitializableInternalMintableERC20 {
uint256 afterChargedAmount uint256 afterChargedAmount
) )
{ {
uint256 mtFeeRate = IController(_CONTROLLER_).getBurnFee(address(this)); uint256 mtFeeRate = IController(_CONTROLLER_).getBurnFeeRate(address(this));
poolFee = DecimalMath.mulFloor(rawAmount, _FEE_RATE_); poolFee = DecimalMath.mulFloor(rawAmount, _FEE_RATE_);
mtFee = DecimalMath.mulFloor(rawAmount, mtFeeRate); mtFee = DecimalMath.mulFloor(rawAmount, mtFeeRate);
afterChargedAmount = rawAmount.add(poolFee).add(mtFee); afterChargedAmount = rawAmount.add(poolFee).add(mtFee);
} }
function isRegisteredFilter(address filter) public view returns (bool) { function isRegisteredFilter(address filter) public view returns (bool) {
return _FILTER_REGISTRY_[i]; return _FILTER_REGISTRY_[filter];
} }
function getFilters() public view returns (address[] memory) { function getFilters() public view returns (address[] memory) {

View File

@@ -8,7 +8,7 @@ pragma experimental ABIEncoderV2;
import {SafeMath} from "../../lib/SafeMath.sol"; import {SafeMath} from "../../lib/SafeMath.sol";
import {IFilterAdmin} from "../intf/IFilterAdmin.sol"; import {IFilterAdmin} from "../intf/IFilterAdmin.sol";
import {IControllerModel} from "../intf/IControllerModel.sol"; import {IController} from "../intf/IController.sol";
import {IERC1155} from "../../intf/IERC1155.sol"; import {IERC1155} from "../../intf/IERC1155.sol";
import {IERC1155Receiver} from "../../intf/IERC1155Receiver.sol"; import {IERC1155Receiver} from "../../intf/IERC1155Receiver.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol"; import {DecimalMath} from "../../lib/DecimalMath.sol";
@@ -32,7 +32,7 @@ contract FilterERC1155V1 is IERC1155Receiver, BaseFilterV1 {
_changeNFTRandomInPrice(priceRules[2], priceRules[3], toggles[1]); _changeNFTRandomInPrice(priceRules[2], priceRules[3], toggles[1]);
_changeNFTTargetOutPrice(priceRules[4], priceRules[5], toggles[2]); _changeNFTTargetOutPrice(priceRules[4], priceRules[5], toggles[2]);
_changeNFTAmount(numParams[2], numParams[3]); _changeNFTAmountRange(numParams[2], numParams[3]);
_changeTokenIdRange(numParams[0], numParams[1]); _changeTokenIdRange(numParams[0], numParams[1]);
for (uint256 i = 0; i < spreadIds.length; i++) { for (uint256 i = 0; i < spreadIds.length; i++) {
@@ -79,12 +79,12 @@ contract FilterERC1155V1 is IERC1155Receiver, BaseFilterV1 {
(uint256 rawPay, ) = queryNFTRandomOut(amount); (uint256 rawPay, ) = queryNFTRandomOut(amount);
paid = IFilterAdmin(_OWNER_).burnFragFrom(msg.sender, rawPay); paid = IFilterAdmin(_OWNER_).burnFragFrom(msg.sender, rawPay);
for (uint256 i = 0; i < amount; i++) { for (uint256 i = 0; i < amount; i++) {
uint256 randomNum = _getRandomOutId() % _TOTAL_NFT_AMOUNT_; uint256 randomNum = _getRandomNum() % _TOTAL_NFT_AMOUNT_;
uint256 sum; uint256 sum;
for (uint256 j = 0; j < _NFT_IDS_.length; j++) { for (uint256 j = 0; j < _NFT_IDS_.length; j++) {
sum += _NFT_RESERVE_[_NFT_IDS_[j]]; sum += _NFT_RESERVE_[_NFT_IDS_[j]];
if (sum >= randomNum) { if (sum >= randomNum) {
_transferOutERC1155(to, _NFT_IDS_[j], 1); _transferOutERC1155(to, j, 1);
break; break;
} }
} }

View File

@@ -10,7 +10,7 @@ pragma experimental ABIEncoderV2;
import {SafeMath} from "../../lib/SafeMath.sol"; import {SafeMath} from "../../lib/SafeMath.sol";
import {IFilterAdmin} from "../intf/IFilterAdmin.sol"; import {IFilterAdmin} from "../intf/IFilterAdmin.sol";
import {IControllerModel} from "../intf/IControllerModel.sol"; import {IController} from "../intf/IController.sol";
import {IERC721} from "../../intf/IERC721.sol"; import {IERC721} from "../../intf/IERC721.sol";
import {IERC721Receiver} from "../../intf/IERC721Receiver.sol"; import {IERC721Receiver} from "../../intf/IERC721Receiver.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol"; import {DecimalMath} from "../../lib/DecimalMath.sol";
@@ -35,7 +35,7 @@ contract FilterERC721V1 is IERC721Receiver, BaseFilterV1 {
_changeNFTRandomInPrice(priceRules[2], priceRules[3], toggles[1]); _changeNFTRandomInPrice(priceRules[2], priceRules[3], toggles[1]);
_changeNFTTargetOutPrice(priceRules[4], priceRules[5], toggles[2]); _changeNFTTargetOutPrice(priceRules[4], priceRules[5], toggles[2]);
_changeNFTAmount(numParams[2], numParams[3]); _changeNFTAmountRange(numParams[2], numParams[3]);
_changeTokenIdRange(numParams[0], numParams[1]); _changeTokenIdRange(numParams[0], numParams[1]);
for (uint256 i = 0; i < spreadIds.length; i++) { for (uint256 i = 0; i < spreadIds.length; i++) {

View File

@@ -10,7 +10,7 @@ import {SafeMath} from "../../lib/SafeMath.sol";
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
import {ICloneFactory} from "../../lib/CloneFactory.sol"; import {ICloneFactory} from "../../lib/CloneFactory.sol";
import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol"; import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol";
import {IFilterModel} from "../../NFTPool/intf/IFilterModel.sol"; import {IFilter} from "../../NFTPool/intf/IFilter.sol";
import {IFilterAdmin} from "../../NFTPool/intf/IFilterAdmin.sol"; import {IFilterAdmin} from "../../NFTPool/intf/IFilterAdmin.sol";
import {IDODONFTApprove} from "../../intf/IDODONFTApprove.sol"; import {IDODONFTApprove} from "../../intf/IDODONFTApprove.sol";
import {IERC20} from "../../intf/IERC20.sol"; import {IERC20} from "../../intf/IERC20.sol";
@@ -20,7 +20,7 @@ interface IFilterV1 {
function init( function init(
address filterAdmin, address filterAdmin,
address nftCollection, address nftCollection,
bool[] memory switches, bool[] memory toggles,
uint256[] memory numParams, uint256[] memory numParams,
uint256[] memory priceRules, uint256[] memory priceRules,
uint256[] memory spreadIds uint256[] memory spreadIds
@@ -35,8 +35,8 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
address constant _ETH_ADDRESS_ = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address constant _ETH_ADDRESS_ = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
mapping(uint256 => address) public _FILTER_TEMPLATES_; mapping(uint256 => address) public _FILTER_TEMPLATES_;
address public _FILTER_ADMIN_TEMPLATE_; address public _FILTER_ADMIN_TEMPLATE_;
address public _DEFAULT_MAINTAINER_; address public _MAINTAINER_;
address public _CONTROLLER_MODEL_; address public _CONTROLLER_;
address public immutable _CLONE_FACTORY_; address public immutable _CLONE_FACTORY_;
address public immutable _DODO_NFT_APPROVE_; address public immutable _DODO_NFT_APPROVE_;
address public immutable _DODO_APPROVE_; address public immutable _DODO_APPROVE_;
@@ -55,8 +55,8 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
) public { ) public {
_CLONE_FACTORY_ = cloneFactory; _CLONE_FACTORY_ = cloneFactory;
_FILTER_ADMIN_TEMPLATE_ = filterAdminTemplate; _FILTER_ADMIN_TEMPLATE_ = filterAdminTemplate;
_CONTROLLER_MODEL_ = controllerModel; _CONTROLLER_ = controllerModel;
_DEFAULT_MAINTAINER_ = defaultMaintainer; _MAINTAINER_ = defaultMaintainer;
_DODO_NFT_APPROVE_ = dodoNftApprove; _DODO_NFT_APPROVE_ = dodoNftApprove;
_DODO_APPROVE_ = dodoApprove; _DODO_APPROVE_ = dodoApprove;
} }
@@ -70,10 +70,10 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
uint256 minMintAmount uint256 minMintAmount
) external { ) external {
for(uint256 i = 0; i < tokenIds.length; i++) { for(uint256 i = 0; i < tokenIds.length; i++) {
require(IFilterModel(filter).isNFTValid(nftCollection,tokenIds[i]), "NOT_REGISTRIED"); require(IFilter(filter).isNFTValid(nftCollection,tokenIds[i]), "NOT_REGISTRIED");
IDODONFTApprove(_DODO_NFT_APPROVE_).claimERC721(nftCollection, msg.sender, filter, tokenIds[i]); IDODONFTApprove(_DODO_NFT_APPROVE_).claimERC721(nftCollection, msg.sender, filter, tokenIds[i]);
} }
uint256 received = IFilterModel(filter).ERC721In(tokenIds, to); uint256 received = IFilter(filter).ERC721In(tokenIds, to);
require(received >= minMintAmount, "MINT_AMOUNT_NOT_ENOUGH"); require(received >= minMintAmount, "MINT_AMOUNT_NOT_ENOUGH");
} }
@@ -83,7 +83,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
address to, address to,
uint256 maxBurnAmount uint256 maxBurnAmount
) external { ) external {
uint256 paid = IFilterModel(filter).ERC721TargetOut(indexes, to); uint256 paid = IFilter(filter).ERC721TargetOut(indexes, to);
require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED"); require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED");
} }
@@ -93,7 +93,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
address to, address to,
uint256 maxBurnAmount uint256 maxBurnAmount
) external { ) external {
uint256 paid = IFilterModel(filter).ERC721RandomOut(amount, to); uint256 paid = IFilter(filter).ERC721RandomOut(amount, to);
require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED"); require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED");
} }
@@ -107,10 +107,10 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
uint256 minMintAmount uint256 minMintAmount
) external { ) external {
for(uint256 i = 0; i < tokenIds.length; i++) { for(uint256 i = 0; i < tokenIds.length; i++) {
require(IFilterModel(filter).isNFTValid(nftCollection,tokenIds[i]), "NOT_REGISTRIED"); require(IFilter(filter).isNFTValid(nftCollection,tokenIds[i]), "NOT_REGISTRIED");
} }
IDODONFTApprove(_DODO_NFT_APPROVE_).claimERC1155Batch(nftCollection, msg.sender, filter, tokenIds, amounts); IDODONFTApprove(_DODO_NFT_APPROVE_).claimERC1155Batch(nftCollection, msg.sender, filter, tokenIds, amounts);
uint256 received = IFilterModel(filter).ERC1155In(tokenIds, to); uint256 received = IFilter(filter).ERC1155In(tokenIds, to);
require(received >= minMintAmount, "MINT_AMOUNT_NOT_ENOUGH"); require(received >= minMintAmount, "MINT_AMOUNT_NOT_ENOUGH");
} }
@@ -121,7 +121,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
address to, address to,
uint256 maxBurnAmount uint256 maxBurnAmount
) external { ) external {
uint256 paid = IFilterModel(filter).ERC1155TargetOut(indexes, amounts, to); uint256 paid = IFilter(filter).ERC1155TargetOut(indexes, amounts, to);
require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED"); require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED");
} }
@@ -131,7 +131,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
address to, address to,
uint256 maxBurnAmount uint256 maxBurnAmount
) external { ) external {
uint256 paid = IFilterModel(filter).ERC1155RandomOut(amount, to); uint256 paid = IFilter(filter).ERC1155RandomOut(amount, to);
require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED"); require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED");
} }
@@ -142,7 +142,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
uint256 filterKey, //1 => FilterERC721V1, 2 => FilterERC1155V1 uint256 filterKey, //1 => FilterERC721V1, 2 => FilterERC1155V1
string[] memory tokenInfo, string[] memory tokenInfo,
uint256[] memory numParams,//0 - initSupply, 1 - fee uint256[] memory numParams,//0 - initSupply, 1 - fee
bool[] memory switches, bool[] memory toggles,
uint256[] memory filterNumParams, //0 - startId, 1 - endId, 2 - maxAmount, 3 - minAmount uint256[] memory filterNumParams, //0 - startId, 1 - endId, 2 - maxAmount, 3 - minAmount
uint256[] memory priceRules, uint256[] memory priceRules,
uint256[] memory spreadIds uint256[] memory spreadIds
@@ -153,7 +153,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
filterKey, filterKey,
newFilterAdmin, newFilterAdmin,
nftCollection, nftCollection,
switches, toggles,
filterNumParams, filterNumParams,
priceRules, priceRules,
spreadIds spreadIds
@@ -168,8 +168,8 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
tokenInfo[0], tokenInfo[0],
tokenInfo[1], tokenInfo[1],
numParams[1], numParams[1],
_CONTROLLER_MODEL_, _CONTROLLER_,
_DEFAULT_MAINTAINER_, _MAINTAINER_,
filters filters
); );
} }
@@ -179,7 +179,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
uint256 key, uint256 key,
address filterAdmin, address filterAdmin,
address nftCollection, address nftCollection,
bool[] memory switches, bool[] memory toggles,
uint256[] memory numParams, //0 - startId, 1 - endId, 2 - maxAmount, 3 - minAmount uint256[] memory numParams, //0 - startId, 1 - endId, 2 - maxAmount, 3 - minAmount
uint256[] memory priceRules, uint256[] memory priceRules,
uint256[] memory spreadIds uint256[] memory spreadIds
@@ -188,7 +188,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
IFilterV1(newFilterV1).init( IFilterV1(newFilterV1).init(
filterAdmin, filterAdmin,
nftCollection, nftCollection,
switches, toggles,
numParams, numParams,
priceRules, priceRules,
spreadIds spreadIds
@@ -214,7 +214,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
uint256[] memory tokenIds = new uint256[](1); uint256[] memory tokenIds = new uint256[](1);
tokenIds[0] = tokenId; tokenIds[0] = tokenId;
uint256 receivedFragAmount = IFilterModel(filter).ERC721In(tokenIds, address(this)); uint256 receivedFragAmount = IFilter(filter).ERC721In(tokenIds, address(this));
_generalApproveMax(filterAdmin, _DODO_APPROVE_, receivedFragAmount); _generalApproveMax(filterAdmin, _DODO_APPROVE_, receivedFragAmount);
@@ -228,16 +228,16 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
//====================== Ownable ======================== //====================== Ownable ========================
function changeDefaultMaintainer(address newMaintainer) external onlyOwner { function changeMaintainer(address newMaintainer) external onlyOwner {
_DEFAULT_MAINTAINER_ = newMaintainer; _MAINTAINER_ = newMaintainer;
} }
function changeFilterAdminTemplate(address newFilterAdminTemplate) external onlyOwner { function changeFilterAdminTemplate(address newFilterAdminTemplate) external onlyOwner {
_FILTER_ADMIN_TEMPLATE_ = newFilterAdminTemplate; _FILTER_ADMIN_TEMPLATE_ = newFilterAdminTemplate;
} }
function changeControllerModel(address newControllerModel) external onlyOwner { function changeController(address newControllerModel) external onlyOwner {
_CONTROLLER_MODEL_ = newControllerModel; _CONTROLLER_ = newControllerModel;
} }
function setFilterTemplate(uint256 idx, address newFilterTemplate) external onlyOwner { function setFilterTemplate(uint256 idx, address newFilterTemplate) external onlyOwner {