This commit is contained in:
owen05
2021-09-09 19:29:50 +08:00
parent e7f6a20cef
commit b652974a60
4 changed files with 92 additions and 182 deletions

View File

@@ -24,202 +24,74 @@ contract FilterAdmin is InitializableInternalMintableERC20, ReentrancyGuard {
address public _CONTROLLER_MODEL_;
address public _DEFAULT_MAINTAINER_;
// ============ Event ============
event ChangeFee(uint256 fee);
function init(
address _owner,
string memory _name,
string memory _symbol,
uint256 fee,
address mtFeeModel,
address controllerModel,
address defaultMaintainer,
address[] memory filters
) external {
super.init(_owner, 0, _name, _symbol, 18);
_FILTER_REGISTRY_ = filters;
_FEE_ = fee;
_CONTROLLER_MODEL_ = mtFeeModel;
_CONTROLLER_MODEL_ = controllerModel;
_DEFAULT_MAINTAINER_ = defaultMaintainer;
}
function ERC721In(
address filter,
address nftContract,
uint256[] memory tokenIds,
uint256 minMintAmount
)
external
preventReentrant
returns (uint256 actualMintAmount)
{
require(isIncludeFilter(filter), "FILTER_NOT_INCLUDE");
require(IFilterModel(filter)._NFT_IN_SWITCH_(), "NFT_IN_CLOSED");
require(IFilterModel(filter).getAvaliableNFTIn() >= tokenIds.length, "EXCEED_MAX_AMOUNT");
uint256 totalPrice = 0;
for(uint256 i = 0; i < tokenIds.length; i++) {
require(IFilterModel(filter).isFilterERC721Pass(nftContract, tokenIds[i]), "NOT_REGISTERED");
totalPrice = totalPrice.add(IFilterModel(filter).getNFTInPrice(nftContract, tokenIds[i]));
IFilterModel(filter).transferInERC721(nftContract, msg.sender, tokenIds[i]);
}
function chargeMint(address user, uint256 totalMintAmount) external {
require(isIncludeFilter(msg.sender), "FILTER_NOT_REGISTRIED");
(uint256 poolFeeAmount, uint256 mtFeeAmount) = _nftInFeeTransfer(totalPrice);
(uint256 poolFeeAmount, uint256 mtFeeAmount) = getMintFee(user, totalMintAmount);
if(poolFeeAmount > 0) _mint(_OWNER_, poolFeeAmount);
if(mtFeeAmount > 0) _mint(_DEFAULT_MAINTAINER_, mtFeeAmount);
actualMintAmount = totalPrice.sub(mtFeeAmount).sub(poolFeeAmount);
require(actualMintAmount >= minMintAmount, "MINT_AMOUNT_NOT_ENOUGH");
_mint(msg.sender, actualMintAmount);
_mint(user, totalMintAmount.sub(poolFeeAmount).sub(mtFeeAmount));
}
function ERC1155In(
address filter,
address nftContract,
uint256[] memory tokenIds,
uint256[] memory amounts,
uint256 minMintAmount
)
external
preventReentrant
returns (uint256 actualMintAmount)
{
require(tokenIds.length == amounts.length, "PARAMS_NOT_MATCH");
require(isIncludeFilter(filter), "FILTER_NOT_INCLUDE");
require(IFilterModel(filter)._NFT_IN_SWITCH_(), "NFT_IN_CLOSED");
require(IFilterModel(filter).getAvaliableNFTIn() >= tokenIds.length, "EXCEED_MAX_AMOUNT");
uint256 totalPrice = 0;
for(uint256 i = 0; i < tokenIds.length; i++) {
require(IFilterModel(filter).isFilterERC1155Pass(nftContract, tokenIds[i], amounts[i]), "NOT_REGISTERED");
totalPrice = totalPrice.add(IFilterModel(filter).getNFTInPrice(nftContract, tokenIds[i]).mul(amounts[i]));
}
function chargeRandomBurn(address user, uint256 totalBurnAmount) external {
require(isIncludeFilter(msg.sender), "FILTER_NOT_REGISTRIED");
(uint256 poolFeeAmount, uint256 mtFeeAmount) = _nftInFeeTransfer(totalPrice);
(uint256 poolFeeAmount, uint256 mtFeeAmount) = getRandomBurnFee(user, totalBurnAmount);
if(poolFeeAmount > 0) _mint(_OWNER_, poolFeeAmount);
if(mtFeeAmount > 0) _mint(_DEFAULT_MAINTAINER_, mtFeeAmount);
actualMintAmount = totalPrice.sub(mtFeeAmount).sub(poolFeeAmount);
require(actualMintAmount >= minMintAmount, "MINT_AMOUNT_NOT_ENOUGH");
_mint(msg.sender, actualMintAmount);
IFilterModel(filter).transferBatchInERC1155(nftContract, msg.sender, tokenIds, amounts);
_burn(user, totalBurnAmount);
}
function ERC721RandomOut(
address filter,
uint256 times,
uint256 maxBurnAmount
)
external
preventReentrant
returns (uint256 actualBurnAmount)
{
require(msg.sender == tx.origin, "ONLY_ALLOW_EOA");
require(isIncludeFilter(filter), "FILTER_NOT_INCLUDE");
require(IFilterModel(filter)._NFT_RANDOM_SWITCH_(), "NFT_RANDOM_CLOSED");
require(IFilterModel(filter).getAvaliableNFTOut() >= times, "EXCEED_MAX_AMOUNT");
uint256 totalPrice = 0;
for(uint256 i = 0; i < times; i++) {
totalPrice = totalPrice.add(IFilterModel(filter).getNFTRandomOutPrice());
(address nftContract, uint256 tokenId) = IFilterModel(filter).getRandomOutId();
IFilterModel(filter).transferOutERC721(nftContract, msg.sender, tokenId);
}
function chargeTargetBurn(address user, uint256 totalBurnAmount) external {
require(isIncludeFilter(msg.sender), "FILTER_NOT_REGISTRIED");
(uint256 poolFeeAmount, uint256 mtFeeAmount) = _nftRandomOutFeeTransfer(totalPrice);
(uint256 poolFeeAmount, uint256 mtFeeAmount) = getTargetBurnFee(user, totalBurnAmount);
if(poolFeeAmount > 0) _mint(_OWNER_, poolFeeAmount);
if(mtFeeAmount > 0) _mint(_DEFAULT_MAINTAINER_, mtFeeAmount);
actualBurnAmount = totalPrice;
require(actualBurnAmount <= maxBurnAmount, "EXTRA_BURN_AMOUNT");
_burn(msg.sender, actualBurnAmount);
_burn(user, totalBurnAmount);
}
function ERC1155RandomOut(
address filter,
uint256 times,
uint256 maxBurnAmount
)
external
preventReentrant
returns (uint256 actualBurnAmount)
{
require(msg.sender == tx.origin, "ONLY_ALLOW_EOA");
require(isIncludeFilter(filter), "FILTER_NOT_INCLUDE");
require(IFilterModel(filter)._NFT_RANDOM_SWITCH_(), "NFT_RANDOM_OUT_CLOSED");
require(IFilterModel(filter).getAvaliableNFTOut() >= times, "EXCEED_MAX_AMOUNT");
uint256 totalPrice = 0;
for(uint256 i = 0; i < times; i++) {
totalPrice = totalPrice.add(IFilterModel(filter).getNFTRandomOutPrice());
(address nftContract, uint256 tokenId) = IFilterModel(filter).getRandomOutId();
IFilterModel(filter).transferOutERC1155(nftContract, msg.sender, tokenId, 1);
}
(uint256 poolFeeAmount, uint256 mtFeeAmount) = _nftRandomOutFeeTransfer(totalPrice);
if(poolFeeAmount > 0) _mint(_OWNER_, poolFeeAmount);
if(mtFeeAmount > 0) _mint(_DEFAULT_MAINTAINER_, mtFeeAmount);
actualBurnAmount = totalPrice;
require(actualBurnAmount <= maxBurnAmount, "EXTRA_BURN_AMOUNT");
_burn(msg.sender, actualBurnAmount);
}
function ERC721TargetOut(
address filter,
address nftContract,
uint256[] memory tokenIds,
uint256 maxBurnAmount
)
external
preventReentrant
returns(uint256 actualBurnAmount)
{
require(isIncludeFilter(filter), "FILTER_NOT_INCLUDE");
require(IFilterModel(filter)._NFT_TARGET_SWITCH_(), "NFT_TARGET_OUT_CLOSED");
require(IFilterModel(filter).getAvaliableNFTOut() >= tokenIds.length, "EXCEED_MAX_AMOUNT");
uint256 totalPrice = 0;
for(uint256 i = 0; i < tokenIds.length; i++) {
totalPrice = totalPrice.add(IFilterModel(filter).getNFTTargetOutPrice(nftContract, tokenIds[i]));
IFilterModel(filter).transferOutERC721(nftContract, msg.sender, tokenIds[i]);
}
(uint256 poolFeeAmount, uint256 mtFeeAmount) = _nftTargetOutFeeTransfer(totalPrice);
if(poolFeeAmount > 0) _mint(_OWNER_, poolFeeAmount);
if(mtFeeAmount > 0) _mint(_DEFAULT_MAINTAINER_, mtFeeAmount);
actualBurnAmount = totalPrice;
require(actualBurnAmount <= maxBurnAmount, "EXTRA_BURN_AMOUNT");
_burn(msg.sender, actualBurnAmount);
}
function ERC1155TargetOut(
address filter,
address nftContract,
uint256[] memory tokenIds,
uint256[] memory amounts,
uint256 maxBurnAmount
)
external
preventReentrant
returns(uint256 actualBurnAmount)
{
require(tokenIds.length == amounts.length, "PARAMS_NOT_MATCH");
require(isIncludeFilter(filter), "FILTER_NOT_INCLUDE");
require(IFilterModel(filter)._NFT_TARGET_SWITCH_(), "NFT_TARGET_OUT_CLOSED");
require(IFilterModel(filter).getAvaliableNFTOut() >= tokenIds.length, "EXCEED_MAX_AMOUNT");
uint256 totalPrice = 0;
for(uint256 i = 0; i < tokenIds.length; i++) {
totalPrice = totalPrice.add(IFilterModel(filter).getNFTTargetOutPrice(nftContract, tokenIds[i]).mul(amounts[i]));
}
(uint256 poolFeeAmount, uint256 mtFeeAmount) = _nftTargetOutFeeTransfer(totalPrice);
if(poolFeeAmount > 0) _mint(_OWNER_, poolFeeAmount);
if(mtFeeAmount > 0) _mint(_DEFAULT_MAINTAINER_, mtFeeAmount);
actualBurnAmount = totalPrice;
require(actualBurnAmount <= maxBurnAmount, "EXTRA_BURN_AMOUNT");
_burn(msg.sender, actualBurnAmount);
IFilterModel(filter).transferBatchOutERC1155(nftContract, msg.sender, tokenIds, amounts);
}
//================ View ================
function getMintFee(address user, uint256 totalMintAmount) public returns (uint256 poolFeeAmount, uint256 mtFeeAmount) {
uint256 mtFeeRate = IControllerModel(_CONTROLLER_MODEL_).getNFTInFee(address(this), user);
poolFeeAmount = DecimalMath.mulFloor(totalMintAmount, _FEE_);
mtFeeAmount = DecimalMath.mulFloor(totalMintAmount, mtFeeRate);
}
function getRandomBurnFee(address user, uint256 totalBurnAmount) public returns (uint256 poolFeeAmount, uint256 mtFeeAmount) {
uint256 mtFeeRate = IControllerModel(_CONTROLLER_MODEL_).getNFTRandomOutFee(address(this), user);
poolFeeAmount = DecimalMath.mulFloor(totalBurnAmount, _FEE_);
mtFeeAmount = DecimalMath.mulFloor(totalBurnAmount, mtFeeRate);
}
function getTargetBurnFee(address user, uint256 totalBurnAmount) public returns (uint256 poolFeeAmount, uint256 mtFeeAmount) {
uint256 mtFeeRate = IControllerModel(_CONTROLLER_MODEL_).getNFTTargetOutFee(address(this), user);
poolFeeAmount = DecimalMath.mulFloor(totalBurnAmount, _FEE_);
mtFeeAmount = DecimalMath.mulFloor(totalBurnAmount, mtFeeRate);
}
function isIncludeFilter(address filter) view public returns (bool) {
uint256 i = 0;
for(; i < _FILTER_REGISTRY_.length; i++) {
@@ -236,28 +108,15 @@ contract FilterAdmin is InitializableInternalMintableERC20, ReentrancyGuard {
return "FADMIN 1.0.0";
}
//=============== Owner ==============
//================= Owner ================
function addFilter(address filter) external onlyOwner {
require(!isIncludeFilter(filter), "FILTER_NOT_INCLUDE");
_FILTER_REGISTRY_.push(filter);
}
//=============== Internal ==============
function _nftInFeeTransfer(uint256 totalPrice) internal returns (uint256 poolFeeAmount, uint256 mtFeeAmount) {
uint256 mtFeeRate = IControllerModel(_CONTROLLER_MODEL_).getNFTInFee(address(this), msg.sender);
poolFeeAmount = DecimalMath.mulFloor(totalPrice, _FEE_);
mtFeeAmount = DecimalMath.mulFloor(totalPrice, mtFeeRate);
}
function _nftRandomOutFeeTransfer(uint256 totalPrice) internal returns (uint256 poolFeeAmount, uint256 mtFeeAmount) {
uint256 mtFeeRate = IControllerModel(_CONTROLLER_MODEL_).getNFTRandomOutFee(address(this), msg.sender);
poolFeeAmount = DecimalMath.mulFloor(totalPrice, _FEE_);
mtFeeAmount = DecimalMath.mulFloor(totalPrice, mtFeeRate);
}
function _nftTargetOutFeeTransfer(uint256 totalPrice) internal returns (uint256 poolFeeAmount, uint256 mtFeeAmount) {
uint256 mtFeeRate = IControllerModel(_CONTROLLER_MODEL_).getNFTTargetOutFee(address(this), msg.sender);
poolFeeAmount = DecimalMath.mulFloor(totalPrice, _FEE_);
mtFeeAmount = DecimalMath.mulFloor(totalPrice, mtFeeRate);
function changeFee(uint256 newFee) external onlyOwner {
require(newFee <= 1e18, "FEE_TOO_LARGE");
_FEE_ = newFee;
emit ChangeFee(newFee);
}
}

View File

@@ -265,5 +265,39 @@ contract FilterModel01 is InitializableOwnable, IERC721Receiver {
function version() virtual external pure returns (string memory) {
return "FILTER_1_ERC721 1.0.0";
//TODO:
function geometricCalc1(uint256 base, uint256 ratio, uint256 times) internal view returns(uint256 newBase, uint256 sum) {
require(times > 0);
//q^(n-1)
uint256 general_coefficient = ratio.powFloor(times - 1);
//an=a1*q^n-1
newBase = base.mul(general_coefficient);
if(ratio == 1e18) {
//na1
sum = base.mul(times);
} else {
//a1(1-q^n)/(1-q)
uint256 denominator = base.mul(1e18.sub(DecimalMath.mulFloor(general_coefficient, ratio)));
sum = denominator.div(1e18.sub(ratio));
}
}
function removeTokenId(uint256 id) internal returns(bool){
uint256[] memory tokenIds = _TOKEN_IDS_;
uint256 i;
for (; i < tokenIds.length; i++) {
if (tokenIds[i] == id) {
tokenIds[i] = tokenIds[tokenIds.length - 1];
break;
}
}
if(i < tokenIds.length) {
_TOKEN_IDS_ = tokenIds;
_TOKEN_IDS_.pop();
return true;
}else {
return false;
}
}
}